From 4728311627497430c233d21d359b284fbb6b182d Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Fri, 2 Apr 2021 17:35:41 +1100 Subject: [PATCH] More fixes --- .../deployment/dev/testing/TestSupport.java | 77 +++++++++++-------- .../dev/testing/runner/JunitTestRunner.java | 14 ++++ .../testing/runner/TestTracingProcessor.java | 4 +- .../test/junit/QuarkusTestExtension.java | 21 ++++- 4 files changed, 79 insertions(+), 37 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java index 8931caf1c0620..5ab7fde7b51db 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestSupport.java @@ -133,40 +133,7 @@ public void start(boolean runTests) { if (context.getApplicationRoot().getTest().isPresent()) { started = true; runTests = true; - if (testCuratedApplication == null) { - testCuratedApplication = curatedApplication.getQuarkusBootstrap().clonedBuilder() - .setMode(QuarkusBootstrap.Mode.TEST) - .setDisableClasspathCache(true) - .setIsolateDeployment(true) - .setTest(true) - .setAuxiliaryApplication(true) - .addAdditionalApplicationArchive(new AdditionalDependency( - Paths.get(context.getApplicationRoot().getTest().get().getClassesPath()), true, - true)) - .build() - .bootstrap(); - compiler = new QuarkusCompiler(testCuratedApplication, compilationProviders, context); - testRunner = new TestRunner(context, testCuratedApplication, new Consumer() { - @Override - public void accept(TestRunResults testRunResults) { - synchronized (TestSupport.this) { - TestSupport.this.testRunResults = testRunResults; - for (CompletableFuture i : resultsListeners) { - i.complete(testRunResults); - } - resultsListeners.clear(); - } - ContinuousTestingWebsocketListener.setLastState( - new ContinuousTestingWebsocketListener.State(true, testRunner.isRunning(), - testRunResults.getTestsPassed() + - testRunResults.getTestsFailed() + - testRunResults.getTestsSkipped(), - testRunResults.getTestsPassed(), - testRunResults.getTestsFailed(), testRunResults.getTestsSkipped())); - - } - }, testState); - } + init(); for (Runnable i : startListeners) { i.run(); } @@ -184,6 +151,48 @@ public void accept(TestRunResults testRunResults) { } } + public void init() { + if (testCuratedApplication == null) { + try { + testCuratedApplication = curatedApplication.getQuarkusBootstrap().clonedBuilder() + .setMode(QuarkusBootstrap.Mode.TEST) + .setDisableClasspathCache(true) + .setIsolateDeployment(true) + .setTest(true) + .setAuxiliaryApplication(true) + .addAdditionalApplicationArchive(new AdditionalDependency( + Paths.get(context.getApplicationRoot().getTest().get().getClassesPath()), true, + true)) + .build() + .bootstrap(); + compiler = new QuarkusCompiler(testCuratedApplication, compilationProviders, context); + testRunner = new TestRunner(context, testCuratedApplication, new Consumer() { + @Override + public void accept(TestRunResults testRunResults) { + synchronized (TestSupport.this) { + TestSupport.this.testRunResults = testRunResults; + for (CompletableFuture i : resultsListeners) { + i.complete(testRunResults); + } + resultsListeners.clear(); + } + ContinuousTestingWebsocketListener.setLastState( + new ContinuousTestingWebsocketListener.State(true, testRunner.isRunning(), + testRunResults.getTestsPassed() + + testRunResults.getTestsFailed() + + testRunResults.getTestsSkipped(), + testRunResults.getTestsPassed(), + testRunResults.getTestsFailed(), testRunResults.getTestsSkipped())); + + } + }, testState); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + public synchronized void stop() { if (started) { started = false; diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/JunitTestRunner.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/JunitTestRunner.java index c2c9f78704ed0..bdc24175f1f9d 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/JunitTestRunner.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/JunitTestRunner.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.Deque; import java.util.HashMap; import java.util.HashSet; @@ -24,12 +25,14 @@ import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; import java.util.logging.LogRecord; import java.util.stream.Collectors; import java.util.stream.Stream; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.Index; import org.jboss.jandex.Indexer; @@ -378,6 +381,17 @@ private static List> discoverTestClasses(DevModeContext devModeContext) throw new RuntimeException(e); } } + ret.sort(Comparator.comparing(new Function, String>() { + @Override + public String apply(Class aClass) { + ClassInfo def = index.getClassByName(DotName.createSimple(aClass.getName())); + AnnotationInstance testProfile = def.classAnnotation(DotName.createSimple("io.quarkus.test.junit.TestProfile")); + if (testProfile == null) { + return ""; + } + return testProfile.value().asClass().name().toString(); + } + })); return ret; } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/TestTracingProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/TestTracingProcessor.java index e508aa9eced0c..4f85522e4996c 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/TestTracingProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/runner/TestTracingProcessor.java @@ -51,8 +51,8 @@ ServiceStartBuildItem startTesting(TestConfig config) { if (config.enabled == TestConfig.Mode.ENABLED) { RuntimeUpdatesProcessor.INSTANCE.getTestSupport().start(); } else if (config.enabled == TestConfig.Mode.PAUSED) { - RuntimeUpdatesProcessor.INSTANCE.getTestSupport().start(false); - RuntimeUpdatesProcessor.INSTANCE.getTestSupport().pause(); + RuntimeUpdatesProcessor.INSTANCE.getTestSupport().init(); + RuntimeUpdatesProcessor.INSTANCE.getTestSupport().stop(); } RuntimeUpdatesProcessor.INSTANCE.getTestSupport().setTags(config.includeTags.orElse(Collections.emptyList()), config.excludeTags); diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java index 9edfb8c8bc5e8..410a9bf5590ba 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java @@ -73,6 +73,8 @@ import io.quarkus.bootstrap.app.QuarkusBootstrap; import io.quarkus.bootstrap.app.RunningQuarkusApplication; import io.quarkus.bootstrap.app.StartupAction; +import io.quarkus.bootstrap.classloading.ClassPathElement; +import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.resolver.model.QuarkusModel; import io.quarkus.bootstrap.runner.Timing; @@ -80,6 +82,7 @@ import io.quarkus.builder.BuildChainBuilder; import io.quarkus.builder.BuildContext; import io.quarkus.builder.BuildStep; +import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem; import io.quarkus.deployment.builditem.TestAnnotationBuildItem; import io.quarkus.deployment.builditem.TestClassBeanBuildItem; import io.quarkus.deployment.builditem.TestClassPredicateBuildItem; @@ -1144,7 +1147,23 @@ public boolean test(String className) { } }).produces(TestClassPredicateBuildItem.class) .build(); - + buildChainBuilder.addBuildStep(new BuildStep() { + @Override + public void execute(BuildContext context) { + //we need to make sure all hot reloadable classes are application classes + context.produce(new ApplicationClassPredicateBuildItem(new Predicate() { + @Override + public boolean test(String s) { + QuarkusClassLoader cl = (QuarkusClassLoader) Thread.currentThread() + .getContextClassLoader(); + //if the class file is present in this (and not the parent) CL then it is an application class + List res = cl + .getElementsWithResource(s.replace(".", "/") + ".class", true); + return !res.isEmpty(); + } + })); + } + }).produces(ApplicationClassPredicateBuildItem.class).build(); buildChainBuilder.addBuildStep(new BuildStep() { @Override public void execute(BuildContext context) {