Skip to content

Commit

Permalink
Revert "Discover tests with ClassLoader other than `ImageClassLoade…
Browse files Browse the repository at this point in the history
…r` (#445)"

This reverts commit 2988364.
  • Loading branch information
melix committed Jul 20, 2023
1 parent 1c4c174 commit 2982d5d
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 311 deletions.
Expand Up @@ -42,21 +42,38 @@
package org.graalvm.junit.platform;

import org.graalvm.junit.platform.config.core.PluginConfigProvider;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeClassInitialization;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.engine.discovery.UniqueIdSelector;
import org.junit.platform.engine.support.descriptor.ClassSource;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.UniqueIdTrackingListener;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@SuppressWarnings("unused")
public final class JUnitPlatformFeature implements Feature {

public static final boolean debug = System.getProperty(TestsDiscoveryHelper.DEBUG) != null;
public final boolean debug = System.getProperty("debug") != null;

private static final NativeImageConfigurationImpl nativeImageConfigImpl = new NativeImageConfigurationImpl();
private final ServiceLoader<PluginConfigProvider> extensionConfigProviders = ServiceLoader.load(PluginConfigProvider.class);
Expand All @@ -69,28 +86,65 @@ public void duringSetup(DuringSetupAccess access) {
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
RuntimeClassInitialization.initializeAtBuildTime(NativeImageJUnitLauncher.class);

List<Path> classpathRoots = access.getApplicationClassPath();
List<Class<?>> discoveredTests;
if (Boolean.parseBoolean(System.getProperty("isolateTestDiscovery"))) {
List<String> discoveredTestNames = TestsDiscoveryHelper.launchTestDiscovery(debug, classpathRoots);
discoveredTests = new ArrayList<>();
for (String discoveredTestName : discoveredTestNames) {
try {
discoveredTests.add(Class.forName(discoveredTestName, false, access.getApplicationClassLoader()));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
List<? extends DiscoverySelector> selectors = getSelectors(classpathRoots);

Launcher launcher = LauncherFactory.create();
TestPlan testplan = discoverTestsAndRegisterTestClassesForReflection(launcher, selectors);
ImageSingletons.add(NativeImageJUnitLauncher.class, new NativeImageJUnitLauncher(launcher, testplan));
}

private List<? extends DiscoverySelector> getSelectors(List<Path> classpathRoots) {
try {
Path outputDir = Paths.get(System.getProperty(UniqueIdTrackingListener.OUTPUT_DIR_PROPERTY_NAME));
String prefix = System.getProperty(UniqueIdTrackingListener.OUTPUT_FILE_PREFIX_PROPERTY_NAME,
UniqueIdTrackingListener.DEFAULT_OUTPUT_FILE_PREFIX);
List<UniqueIdSelector> selectors = readAllFiles(outputDir, prefix)
.map(DiscoverySelectors::selectUniqueId)
.collect(Collectors.toList());
if (!selectors.isEmpty()) {
System.out.printf(
"[junit-platform-native] Running in 'test listener' mode using files matching pattern [%s*] "
+ "found in folder [%s] and its subfolders.%n",
prefix, outputDir.toAbsolutePath());
return selectors;
}
} else {
TestsDiscoveryHelper helper = new TestsDiscoveryHelper(debug, classpathRoots);
discoveredTests = helper.discoverTests();
} catch (Exception ex) {
debug("Failed to read UIDs from UniqueIdTrackingListener output files: " + ex.getMessage());
}
for (Class<?> discoveredTest : discoveredTests) {
registerTestClassForReflection(discoveredTest);

System.out.println("[junit-platform-native] Running in 'test discovery' mode. Note that this is a fallback mode.");
if (debug) {
classpathRoots.forEach(entry -> debug("Selecting classpath root: " + entry));
}
return DiscoverySelectors.selectClasspathRoots(new HashSet<>(classpathRoots));
}

/**
* Use the JUnit Platform Launcher to discover tests and register classes
* for reflection.
*/
private TestPlan discoverTestsAndRegisterTestClassesForReflection(Launcher launcher,
List<? extends DiscoverySelector> selectors) {

LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectors)
.build();

ImageSingletons.add(NativeImageJUnitLauncher.class,
new NativeImageJUnitLauncher(new TestsDiscoveryHelper(debug, classpathRoots)));
TestPlan testPlan = launcher.discover(request);

testPlan.getRoots().stream()
.flatMap(rootIdentifier -> testPlan.getDescendants(rootIdentifier).stream())
.map(TestIdentifier::getSource)
.filter(Optional::isPresent)
.map(Optional::get)
.filter(ClassSource.class::isInstance)
.map(ClassSource.class::cast)
.map(ClassSource::getJavaClass)
.forEach(this::registerTestClassForReflection);

return testPlan;
}

private void registerTestClassForReflection(Class<?> clazz) {
Expand All @@ -116,11 +170,26 @@ public static void debug(String format, Object... args) {
}

public static boolean debug() {
if (!ImageInfo.inImageCode()) {
return debug;
} else {
return ImageSingletons.lookup(JUnitPlatformFeature.class).debug;
return ImageSingletons.lookup(JUnitPlatformFeature.class).debug;
}

private Stream<String> readAllFiles(Path dir, String prefix) throws IOException {
return findFiles(dir, prefix).map(outputFile -> {
try {
return Files.readAllLines(outputFile);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}).flatMap(List::stream);
}

private static Stream<Path> findFiles(Path dir, String prefix) throws IOException {
if (!Files.exists(dir)) {
return Stream.empty();
}
return Files.find(dir, Integer.MAX_VALUE,
(path, basicFileAttributes) -> (basicFileAttributes.isRegularFile()
&& path.getFileName().toString().startsWith(prefix)));
}

}
Expand Up @@ -43,8 +43,6 @@

import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestPlan;
Expand All @@ -61,17 +59,11 @@ public class NativeImageJUnitLauncher {
static final String DEFAULT_OUTPUT_FOLDER = Paths.get("test-results-native").resolve("test").toString();

final Launcher launcher;
TestPlan testPlan;
final TestsDiscoveryHelper testsDiscoveryHelper;
final TestPlan testPlan;

@Platforms(Platform.HOSTED_ONLY.class)
public NativeImageJUnitLauncher(TestsDiscoveryHelper testsDiscoveryHelper) {
this.testsDiscoveryHelper = testsDiscoveryHelper;
launcher = testsDiscoveryHelper.getLauncher();
}

private void discoverTests() {
testPlan = testsDiscoveryHelper.discoverTestPlan();
public NativeImageJUnitLauncher(Launcher launcher, TestPlan testPlan) {
this.launcher = launcher;
this.testPlan = testPlan;
}

public void registerTestExecutionListeners(TestExecutionListener testExecutionListener) {
Expand Down Expand Up @@ -123,8 +115,7 @@ public static void main(String... args) {

PrintWriter out = new PrintWriter(System.out);
NativeImageJUnitLauncher launcher = ImageSingletons.lookup(NativeImageJUnitLauncher.class);
//Discover the test plan at runtime.
launcher.discoverTests();

if (!silent) {
out.println("JUnit Platform on Native Image - report");
out.println("----------------------------------------\n");
Expand Down

0 comments on commit 2982d5d

Please sign in to comment.