diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java index 6659b7496766f..5c6b2ecfcfb44 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java @@ -26,6 +26,7 @@ import io.quarkus.dev.spi.DevModeType; import io.quarkus.dev.spi.HotReplacementSetup; import io.quarkus.runner.bootstrap.AugmentActionImpl; +import io.quarkus.runtime.Quarkus; /** * The main entry point of quarkus:test @@ -116,7 +117,6 @@ public void accept(CuratedApplication o, Map params) { oo.writeObject(potentialContext); context = (DevModeContext) new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())).readObject(); } - augmentAction = new AugmentActionImpl(curatedApplication); RuntimeUpdatesProcessor.INSTANCE = setupRuntimeCompilation(context, (Path) params.get(APP_ROOT)); @@ -146,6 +146,7 @@ public void run() { } } }, "Quarkus Shutdown Thread")); + Quarkus.waitForExit(); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestConsoleHandler.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestConsoleHandler.java index 99b70431810be..c97cc3903b2fd 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestConsoleHandler.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestConsoleHandler.java @@ -27,16 +27,19 @@ import io.quarkus.deployment.dev.RuntimeUpdatesProcessor; import io.quarkus.dev.console.InputHandler; import io.quarkus.dev.console.QuarkusConsole; +import io.quarkus.dev.spi.DevModeType; public class TestConsoleHandler implements TestListener { private static final Logger log = Logger.getLogger("io.quarkus.test"); - public static final String PAUSED_PROMPT = YELLOW + "Tests paused, press [r] to resume" + RESET; + public static final String PAUSED_PROMPT = YELLOW + "Tests paused, press [r] to resume, [h] for more options>" + RESET; public static final String FIRST_RUN_PROMPT = YELLOW + "Running Tests for the first time" + RESET; public static final String RUNNING_PROMPT = "Press [r] to re-run, [v] to view full results, [p] to pause, [h] for more options>"; public static final String ABORTED_PROMPT = "Test run aborted."; + final DevModeType devModeType; + boolean firstRun = true; boolean disabled = true; boolean currentlyFailing = false; @@ -44,6 +47,10 @@ public class TestConsoleHandler implements TestListener { volatile TestController testController; private String lastStatus; + public TestConsoleHandler(DevModeType devModeType) { + this.devModeType = devModeType; + } + public void install() { QuarkusConsole.INSTANCE.pushInputHandler(inputHandler); QuarkusClassLoader classLoader = (QuarkusClassLoader) getClass().getClassLoader(); @@ -59,39 +66,49 @@ public void run() { @Override public void handleInput(int[] keys) { - if (disabled) { - for (int i : keys) { - if (i == 'r') { - promptHandler.setStatus(YELLOW + "Starting tests" + RESET); - TestSupport.instance().get().start(); + //common commands, work every time + for (int k : keys) { + if (k == 'h') { + printUsage(); + } else if (k == 'i' && devModeType != DevModeType.TEST_ONLY) { + testController.toggleInstrumentation(); + } else if (k == 'l' && devModeType != DevModeType.TEST_ONLY) { + RuntimeUpdatesProcessor.INSTANCE.toggleLiveReloadEnabled(); + } else if (k == 's' && devModeType != DevModeType.TEST_ONLY) { + try { + RuntimeUpdatesProcessor.INSTANCE.doScan(true, true); + } catch (IOException e) { + log.error("Live reload scan failed", e); } - } - } else if (!firstRun) { - //TODO: some of this is a bit yuck, this needs some work - for (int k : keys) { - if (k == 'r') { - testController.runAllTests(); - } else if (k == 'f') { - testController.runFailedTests(); - } else if (k == 'v') { - testController.printFullResults(); - } else if (k == 'i') { - testController.toggleInstrumentation(); - } else if (k == 'o') { - testController.toggleTestOutput(); - } else if (k == 'p') { - TestSupport.instance().get().stop(); - } else if (k == 'h') { - printUsage(); - } else if (k == 'b') { - testController.toggleBrokenOnlyMode(); - } else if (k == 'l') { - RuntimeUpdatesProcessor.INSTANCE.toggleLiveReloadEnabled(); - } else if (k == 's') { - try { - RuntimeUpdatesProcessor.INSTANCE.doScan(true, true); - } catch (IOException e) { - log.error("Live reload scan failed", e); + } else if (k == 'q') { + //we don't call Quarkus.exit() here as that would just result + //in a 'press any key to restart' prompt + new Thread(new Runnable() { + @Override + public void run() { + System.exit(0); + } + }, "Quarkus exit thread").run(); + } else { + if (disabled) { + if (k == 'r') { + promptHandler.setStatus(YELLOW + "Starting tests" + RESET); + TestSupport.instance().get().start(); + } + } else if (!firstRun) { + //TODO: some of this is a bit yuck, this needs some work + if (k == 'r') { + testController.runAllTests(); + } else if (k == 'f') { + testController.runFailedTests(); + } else if (k == 'v') { + testController.printFullResults(); + } else if (k == 'o' && devModeType != DevModeType.TEST_ONLY) { + testController.toggleTestOutput(); + } else if (k == 'p') { + TestSupport.instance().get().stop(); + } else if (k == 'b') { + testController.toggleBrokenOnlyMode(); } } } @@ -112,17 +129,27 @@ public void listenerRegistered(TestController testController) { public void printUsage() { System.out.println(RESET + "\nThe following commands are available:"); - System.out.println(helpOption("r", "Re-run all tests")); - System.out.println(helpOption("f", "Re-run failed tests")); - System.out.println(helpOption("b", "Toggle 'broken only' mode, where only failing tests are run", - testController.isBrokenOnlyMode())); - System.out.println(helpOption("v", "Print failures from the last test run")); - System.out.println(helpOption("o", "Toggle test output", testController.isDisplayTestOutput())); - System.out.println(helpOption("p", "Pause tests")); - System.out.println(helpOption("i", "Toggle instrumentation based reload", testController.isInstrumentationEnabled())); - System.out.println(helpOption("l", "Toggle live reload", testController.isLiveReloadEnabled())); - System.out.println(helpOption("s", "Force live reload scan")); + if (disabled) { + System.out.println(helpOption("r", "Resume testing")); + } else { + System.out.println(helpOption("r", "Re-run all tests")); + System.out.println(helpOption("f", "Re-run failed tests")); + System.out.println(helpOption("b", "Toggle 'broken only' mode, where only failing tests are run", + testController.isBrokenOnlyMode())); + System.out.println(helpOption("v", "Print failures from the last test run")); + if (devModeType != DevModeType.TEST_ONLY) { + System.out.println(helpOption("o", "Toggle test output", testController.isDisplayTestOutput())); + } + System.out.println(helpOption("p", "Pause tests")); + } + if (devModeType != DevModeType.TEST_ONLY) { + System.out + .println(helpOption("i", "Toggle instrumentation based reload", testController.isInstrumentationEnabled())); + System.out.println(helpOption("l", "Toggle live reload", testController.isLiveReloadEnabled())); + System.out.println(helpOption("s", "Force live reload scan")); + } System.out.println(helpOption("h", "Display this help")); + System.out.println(helpOption("q", "Quit")); } @Override diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestTracingProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestTracingProcessor.java index 502a21101d3a0..95dc3e18acd94 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestTracingProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/TestTracingProcessor.java @@ -45,7 +45,8 @@ LogCleanupFilterBuildItem handle() { @BuildStep(onlyIf = IsDevelopment.class) @Produce(TestSetupBuildItem.class) - void setupConsole(TestConfig config, BuildProducer testListenerBuildItemBuildProducer) { + void setupConsole(TestConfig config, BuildProducer testListenerBuildItemBuildProducer, + LaunchModeBuildItem launchModeBuildItem) { if (!TestSupport.instance().isPresent() || config.continuousTesting == TestConfig.Mode.DISABLED || config.flatClassPath) { return; @@ -56,7 +57,7 @@ void setupConsole(TestConfig config, BuildProducer testLi consoleInstalled = true; if (config.console) { ConsoleHelper.installConsole(config); - TestConsoleHandler consoleHandler = new TestConsoleHandler(); + TestConsoleHandler consoleHandler = new TestConsoleHandler(launchModeBuildItem.getDevModeType().get()); consoleHandler.install(); testListenerBuildItemBuildProducer.produce(new TestListenerBuildItem(consoleHandler)); } @@ -65,14 +66,16 @@ void setupConsole(TestConfig config, BuildProducer testLi @BuildStep(onlyIfNot = IsNormal.class) @Produce(LogHandlerBuildItem.class) @Produce(TestSetupBuildItem.class) - ServiceStartBuildItem startTesting(TestConfig config, LiveReloadBuildItem liveReloadBuildItem, + @Produce(ServiceStartBuildItem.class) + void startTesting(TestConfig config, LiveReloadBuildItem liveReloadBuildItem, LaunchModeBuildItem launchModeBuildItem, List testListenerBuildItems) { if (!TestSupport.instance().isPresent() || config.continuousTesting == TestConfig.Mode.DISABLED || config.flatClassPath) { - return null; + return; } - if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) { - return null; + DevModeType devModeType = launchModeBuildItem.getDevModeType().orElse(null); + if (devModeType == null || !devModeType.isContinuousTestingSupported()) { + return; } TestSupport testSupport = TestSupport.instance().get(); for (TestListenerBuildItem i : testListenerBuildItems) { @@ -99,7 +102,6 @@ public void run() { testSupport.stop(); } }); - return null; } @BuildStep(onlyIf = IsTest.class) diff --git a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java index 11af5d8c63976..c4c6ce571e444 100644 --- a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java +++ b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java @@ -128,6 +128,11 @@ public AugmentActionImpl(CuratedApplication curatedApplication, List() { @Override public void accept(DevModeContext devModeContext) { + devModeContext.setMode(QuarkusBootstrap.Mode.CONTINUOUS_TEST); devModeContext.setAlternateEntryPoint(IsolatedTestModeMain.class.getName()); } }); diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/tests/TestsProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/tests/TestsProcessor.java index 0da65276a49cf..3693f7b9c429e 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/tests/TestsProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/tests/TestsProcessor.java @@ -47,7 +47,8 @@ public void setupTestRoutes( LaunchModeBuildItem launchModeBuildItem, BuildProducer routeBuildItemBuildProducer, BuildProducer testListenerBuildItemBuildProducer) throws IOException { - if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) { + DevModeType devModeType = launchModeBuildItem.getDevModeType().orElse(null); + if (devModeType == null || !devModeType.isContinuousTestingSupported()) { return; } diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/BootstrapProfile.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/BootstrapProfile.java index 9353be566503b..3642f42b0954f 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/BootstrapProfile.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/BootstrapProfile.java @@ -52,6 +52,7 @@ public static String getActiveProfile(QuarkusBootstrap.Mode mode) { switch (mode) { case REMOTE_DEV_SERVER: case DEV: + case CONTINUOUS_TEST: return DEV; case REMOTE_DEV_CLIENT: case PROD: diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java index 59352c6a3fa9d..76ea85a96bec5 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/QuarkusBootstrap.java @@ -565,6 +565,7 @@ public enum Mode { TEST, PROD, REMOTE_DEV_SERVER, - REMOTE_DEV_CLIENT; + REMOTE_DEV_CLIENT, + CONTINUOUS_TEST; } }