Skip to content

Commit 23494be

Browse files
committed
Use JUnit dry-run for JVM tests run
1 parent 7dc51bf commit 23494be

File tree

6 files changed

+74
-45
lines changed

6 files changed

+74
-45
lines changed

common/utils/src/main/java/org/graalvm/buildtools/utils/SharedConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public interface SharedConstants {
7878
String AGENT_OUTPUT_DIRECTORY_MARKER = "{output_dir}";
7979
String AGENT_OUTPUT_DIRECTORY_OPTION = "config-output-dir=";
8080
String METADATA_REPO_URL_TEMPLATE = "https://github.com/oracle/graalvm-reachability-metadata/releases/download/%1$s/graalvm-reachability-metadata-%1$s.zip";
81+
String SKIP_JVM_TESTS = "skipJVMTests";
8182
/**
8283
* The default metadata repository version. Maintained for backwards
8384
* compatibility.

native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ public class NativeImagePlugin implements Plugin<Project> {
170170
public static final Attribute<Boolean> JAR_ANALYSIS_ATTRIBUTE = Attribute.of("jar-analysis", Boolean.class);
171171

172172
private static final String JUNIT_PLATFORM_LISTENERS_UID_TRACKING_ENABLED = "junit.platform.listeners.uid.tracking.enabled";
173+
private static final String JUNIT_PLATFORM_DRY_RUN_ENABLED = "junit.platform.execution.dryRun.enabled";
173174
private static final String JUNIT_PLATFORM_LISTENERS_UID_TRACKING_OUTPUT_DIR = "junit.platform.listeners.uid.tracking.output.dir";
174175
private static final String REPOSITORY_COORDINATES = "org.graalvm.buildtools:graalvm-reachability-metadata:" + VersionInfo.NBT_VERSION + ":repository@zip";
175176
private static final String DEFAULT_URI = String.format(METADATA_REPO_URL_TEMPLATE, VersionInfo.METADATA_REPO_VERSION);
@@ -679,6 +680,16 @@ public void registerTestBinary(Project project,
679680
test.getOutputs().dir(testList);
680681
// Set system property read by the UniqueIdTrackingListener.
681682
test.systemProperty(JUNIT_PLATFORM_LISTENERS_UID_TRACKING_ENABLED, true);
683+
684+
// Set system property to skip execution of JVM tests before native tests
685+
if (shouldSkipJVMTests()) {
686+
if (graalExtension.getAgent().getEnabled().get()) {
687+
throw new IllegalStateException("Native Image Agent and skipJVMTests cannot be used at the same time.");
688+
}
689+
690+
test.systemProperty(JUNIT_PLATFORM_DRY_RUN_ENABLED, true);
691+
}
692+
682693
TrackingDirectorySystemPropertyProvider directoryProvider = project.getObjects().newInstance(TrackingDirectorySystemPropertyProvider.class);
683694
directoryProvider.getDirectory().set(testListDirectory);
684695
test.getJvmArgumentProviders().add(directoryProvider);
@@ -713,6 +724,11 @@ public void registerTestBinary(Project project,
713724
});
714725
}
715726

727+
private boolean shouldSkipJVMTests() {
728+
String option = System.getProperty(SharedConstants.SKIP_JVM_TESTS);
729+
return (option != null && option.isEmpty()) || Boolean.parseBoolean(option);
730+
}
731+
716732
/**
717733
* Returns a provider which prefers the CLI arguments over the configured
718734
* extension value.

native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MergeAgentFilesMojo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ private void mergeForGivenDir(String agentOutputDirectory) throws MojoExecutionE
116116
File baseDir = new File(agentOutputDirectory);
117117
if (baseDir.exists()) {
118118
List<File> sessionDirectories = sessionDirectoriesFrom(baseDir.listFiles()).collect(Collectors.toList());
119-
if (sessionDirectories.size() == 0) {
119+
if (sessionDirectories.isEmpty()) {
120120
sessionDirectories = Collections.singletonList(baseDir);
121121
}
122122

native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeExtension.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,14 @@
6767
import static org.graalvm.buildtools.utils.NativeImageConfigurationUtils.getNativeImage;
6868

6969
/**
70-
* This extension is responsible for configuring the Surefire plugin to enable
70+
* This extension is responsible for configuring the Surefire and the Failsafe plugins to enable
7171
* the JUnit Platform test listener and registering the native dependency transparently.
7272
*/
7373
@Component(role = AbstractMavenLifecycleParticipant.class, hint = "native-build-tools")
7474
public class NativeExtension extends AbstractMavenLifecycleParticipant implements LogEnabled {
7575

7676
private static final String JUNIT_PLATFORM_LISTENERS_UID_TRACKING_ENABLED = "junit.platform.listeners.uid.tracking.enabled";
77+
private static final String JUNIT_PLATFORM_DRY_RUN_ENABLED = "junit.platform.execution.dryRun.enabled";
7778
private static final String JUNIT_PLATFORM_LISTENERS_UID_TRACKING_OUTPUT_DIR = "junit.platform.listeners.uid.tracking.output.dir";
7879
private static final String NATIVEIMAGE_IMAGECODE = "org.graalvm.nativeimage.imagecode";
7980

@@ -134,11 +135,16 @@ public void afterProjectsRead(MavenSession session) {
134135
throw new RuntimeException(e);
135136
}
136137

138+
boolean skipJVMTests = shouldSkipJVMTests(session);
139+
if (skipJVMTests && agent.isEnabled()) {
140+
throw new IllegalStateException("Native Image Agent and skipJVMTests cannot be used at the same time.");
141+
}
142+
137143
// Test configuration
138144
List<String> plugins = List.of("maven-surefire-plugin", "maven-failsafe-plugin");
139145
for (String pluginName : plugins) {
140146
withPlugin(build, pluginName, plugin -> {
141-
configureJunitListener(plugin, testIdsDir);
147+
configureJunitListener(plugin, testIdsDir, skipJVMTests);
142148
if (agent.isEnabled()) {
143149
List<String> agentOptions = agent.getAgentCommandLine();
144150
configureAgentForPlugin(plugin, buildAgentArgument(target, Context.test, agentOptions));
@@ -188,6 +194,11 @@ public void afterProjectsRead(MavenSession session) {
188194
}
189195
}
190196

197+
private static boolean shouldSkipJVMTests(MavenSession session) {
198+
String option = session.getSystemProperties().getProperty(SharedConstants.SKIP_JVM_TESTS);
199+
return (option != null && option.isEmpty()) || Boolean.parseBoolean(option);
200+
}
201+
191202
private static void setupMergeAgentFiles(PluginExecution exec, Xpp3Dom configuration, Context context) {
192203
List<String> goals = new ArrayList<>();
193204
goals.add("merge-agent-files");
@@ -217,12 +228,19 @@ private static void configureAgentForPlugin(Plugin plugin, String agentArgument)
217228
});
218229
}
219230

220-
private static void configureJunitListener(Plugin surefirePlugin, String testIdsDir) {
221-
updatePluginConfiguration(surefirePlugin, (exec, configuration) -> {
231+
private static void configureJunitListener(Plugin plugin, String testIdsDir, boolean skipJVMTests) {
232+
updatePluginConfiguration(plugin, (exec, configuration) -> {
222233
Xpp3Dom systemProperties = findOrAppend(configuration, "systemProperties");
234+
223235
Xpp3Dom junitTracking = findOrAppend(systemProperties, JUNIT_PLATFORM_LISTENERS_UID_TRACKING_ENABLED);
224-
Xpp3Dom testIdsProperty = findOrAppend(systemProperties, JUNIT_PLATFORM_LISTENERS_UID_TRACKING_OUTPUT_DIR);
225236
junitTracking.setValue("true");
237+
238+
if (skipJVMTests) {
239+
Xpp3Dom junitDryRun = findOrAppend(systemProperties, JUNIT_PLATFORM_DRY_RUN_ENABLED);
240+
junitDryRun.setValue("true");
241+
}
242+
243+
Xpp3Dom testIdsProperty = findOrAppend(systemProperties, JUNIT_PLATFORM_LISTENERS_UID_TRACKING_OUTPUT_DIR);
226244
testIdsProperty.setValue(testIdsDir);
227245
});
228246
}

native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/AgentUtils.java

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@
5656
import java.util.List;
5757
import java.util.stream.Collectors;
5858

59-
import static org.graalvm.buildtools.utils.Utils.parseBoolean;
60-
6159
public abstract class AgentUtils {
6260

61+
private static final String STANDARD = "standard";
62+
private static final String CONDITIONAL = "conditional";
63+
private static final String DIRECT = "direct";
64+
private static final String DISABLED = "disabled";
65+
6366
public static AgentMode getAgentMode(Xpp3Dom agent) throws Exception {
6467
Xpp3Dom defaultModeNode = Xpp3DomParser.getTagByName(agent, "defaultMode");
6568
// if default mode is not provided in pom, return Standard mode
@@ -72,13 +75,13 @@ public static AgentMode getAgentMode(Xpp3Dom agent) throws Exception {
7275
AgentMode agentMode;
7376
String mode = defaultModeNode.getValue();
7477
switch (mode.toLowerCase()) {
75-
case "standard":
76-
agentMode = new StandardAgentMode();
77-
break;
78-
case "disabled":
78+
case DISABLED:
7979
agentMode = new DisabledAgentMode();
8080
break;
81-
case "conditional":
81+
case STANDARD:
82+
agentMode = new StandardAgentMode();
83+
break;
84+
case CONDITIONAL:
8285
// conditional mode needs few more options declared in xml
8386
if (agentModes == null) {
8487
throw new RuntimeException("Tag <modes> not provided in agent configuration.");
@@ -91,12 +94,12 @@ public static AgentMode getAgentMode(Xpp3Dom agent) throws Exception {
9194
throw new Exception("UserCodeFilterPath must be provided in agent configuration");
9295
}
9396

94-
Boolean parallel = parseBooleanNode(agentModes, "parallel");
97+
Boolean parallel = Utils.parseBooleanNode(agentModes, "parallel");
9598
agentMode = new ConditionalAgentMode(userCodeFilterPathNode.getValue(),
9699
extraFilterPathNode != null ? extraFilterPathNode.getValue() : "",
97100
parallel == null ? false : parallel);
98101
break;
99-
case "direct":
102+
case DIRECT:
100103
// direct mode is given
101104
if (agentModes == null) {
102105
throw new RuntimeException("Tag <modes> not provided in agent configuration.");
@@ -138,11 +141,11 @@ public static AgentConfiguration collectAgentProperties(MavenSession session, Xp
138141

139142
ArrayList<String> callerFilterFiles = (ArrayList<String>) getFilterFiles(options, "callerFilterFiles");
140143
ArrayList<String> accessFilterFiles = (ArrayList<String>) getFilterFiles(options, "accessFilterFiles");
141-
Boolean builtinCallerFilter = parseBooleanNode(options, "builtinCallerFilter");
142-
Boolean builtinHeuristicFilter = parseBooleanNode(options, "builtinHeuristicFilter");
143-
Boolean enableExperimentalPredefinedClasses = parseBooleanNode(options, "enableExperimentalPredefinedClasses");
144-
Boolean enableExperimentalUnsafeAllocationTracing = parseBooleanNode(options, "enableExperimentalUnsafeAllocationTracing");
145-
Boolean trackReflectionMetadata = parseBooleanNode(options, "trackReflectionMetadata");
144+
Boolean builtinCallerFilter = Utils.parseBooleanNode(options, "builtinCallerFilter");
145+
Boolean builtinHeuristicFilter = Utils.parseBooleanNode(options, "builtinHeuristicFilter");
146+
Boolean enableExperimentalPredefinedClasses = Utils.parseBooleanNode(options, "enableExperimentalPredefinedClasses");
147+
Boolean enableExperimentalUnsafeAllocationTracing = Utils.parseBooleanNode(options, "enableExperimentalUnsafeAllocationTracing");
148+
Boolean trackReflectionMetadata = Utils.parseBooleanNode(options, "trackReflectionMetadata");
146149

147150
AgentMode mode;
148151
try {
@@ -175,7 +178,7 @@ private static Boolean isAgentEnabledInCmd(MavenSession session) {
175178
String systemProperty = session.getSystemProperties().getProperty("agent");
176179
if (systemProperty != null) {
177180
// -Dagent=[true|false] overrides configuration in the POM.
178-
return parseBoolean("agent system property", systemProperty);
181+
return Boolean.parseBoolean(systemProperty);
179182
}
180183

181184
return null;
@@ -187,7 +190,7 @@ private static boolean isAgentEnabled(MavenSession session, Xpp3Dom agent) {
187190
return cmdEnable;
188191
}
189192

190-
Boolean val = parseBooleanNode(agent, "enabled");
193+
Boolean val = Utils.parseBooleanNode(agent, "enabled");
191194
if (val == null) {
192195
return false;
193196
}
@@ -210,18 +213,4 @@ private static List<String> getFilterFiles(Xpp3Dom root, String type) {
210213
.map(Xpp3Dom::getValue)
211214
.collect(Collectors.toCollection(ArrayList::new));
212215
}
213-
214-
private static Boolean parseBooleanNode(Xpp3Dom root, String name) {
215-
if (root == null) {
216-
return null;
217-
}
218-
219-
Xpp3Dom node = Xpp3DomParser.getTagByName(root, name);
220-
if (node == null) {
221-
// if node is not provided, default value is false
222-
return null;
223-
}
224-
225-
return Utils.parseBoolean("<" + name + ">", node.getValue());
226-
}
227216
}

native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/Utils.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,22 @@
4040
*/
4141
package org.graalvm.buildtools.utils;
4242

43+
import org.codehaus.plexus.util.xml.Xpp3Dom;
44+
4345
public abstract class Utils {
44-
public static boolean parseBoolean(String description, String value) {
45-
value = assertNotEmptyAndTrim(value, description + " must have a value").toLowerCase();
46-
switch (value) {
47-
case "true":
48-
return true;
49-
case "false":
50-
return false;
51-
default:
52-
throw new IllegalStateException(description + " must have a value of 'true' or 'false'");
46+
47+
public static Boolean parseBooleanNode(Xpp3Dom root, String name) {
48+
if (root == null) {
49+
return null;
5350
}
51+
52+
Xpp3Dom node = Xpp3DomParser.getTagByName(root, name);
53+
if (node == null) {
54+
// if node is not provided, default value is false
55+
return null;
56+
}
57+
58+
return Boolean.parseBoolean(node.getValue());
5459
}
5560

5661
public static String assertNotEmptyAndTrim(String input, String message) {

0 commit comments

Comments
 (0)