Skip to content

Commit

Permalink
Merge pull request #17851 from stuartwdouglas/testing-input
Browse files Browse the repository at this point in the history
Polish console input
  • Loading branch information
stuartwdouglas authored Jun 11, 2021
2 parents d88f128 + 59b71ef commit b97c211
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -116,7 +117,6 @@ public void accept(CuratedApplication o, Map<String, Object> 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));

Expand Down Expand Up @@ -146,6 +146,7 @@ public void run() {
}
}
}, "Quarkus Shutdown Thread"));
Quarkus.waitForExit();
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,30 @@
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;
volatile InputHandler.ConsoleStatus promptHandler;
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();
Expand All @@ -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();
}
}
}
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ LogCleanupFilterBuildItem handle() {

@BuildStep(onlyIf = IsDevelopment.class)
@Produce(TestSetupBuildItem.class)
void setupConsole(TestConfig config, BuildProducer<TestListenerBuildItem> testListenerBuildItemBuildProducer) {
void setupConsole(TestConfig config, BuildProducer<TestListenerBuildItem> testListenerBuildItemBuildProducer,
LaunchModeBuildItem launchModeBuildItem) {
if (!TestSupport.instance().isPresent() || config.continuousTesting == TestConfig.Mode.DISABLED
|| config.flatClassPath) {
return;
Expand All @@ -56,7 +57,7 @@ void setupConsole(TestConfig config, BuildProducer<TestListenerBuildItem> 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));
}
Expand All @@ -65,14 +66,16 @@ void setupConsole(TestConfig config, BuildProducer<TestListenerBuildItem> 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<TestListenerBuildItem> 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) {
Expand All @@ -99,7 +102,6 @@ public void run() {
testSupport.stop();
}
});
return null;
}

@BuildStep(onlyIf = IsTest.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public AugmentActionImpl(CuratedApplication curatedApplication, List<Consumer<Bu
launchMode = LaunchMode.NORMAL;
devModeType = DevModeType.REMOTE_LOCAL_SIDE;
break;
case CONTINUOUS_TEST:
//the process that actually launches the tests is a dev mode process
launchMode = LaunchMode.DEVELOPMENT;
devModeType = DevModeType.TEST_ONLY;
break;
case REMOTE_DEV_SERVER:
launchMode = LaunchMode.DEVELOPMENT;
devModeType = DevModeType.REMOTE_SERVER_SIDE;
Expand Down
18 changes: 14 additions & 4 deletions core/devmode-spi/src/main/java/io/quarkus/dev/spi/DevModeType.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package io.quarkus.dev.spi;

public enum DevModeType {
LOCAL,
REMOTE_LOCAL_SIDE,
REMOTE_SERVER_SIDE,
TEST_ONLY
LOCAL(true),
REMOTE_LOCAL_SIDE(false),
REMOTE_SERVER_SIDE(false),
TEST_ONLY(true);

final boolean continuousTestingSupported;

DevModeType(boolean continuousTestingSupported) {
this.continuousTestingSupported = continuousTestingSupported;
}

public boolean isContinuousTestingSupported() {
return continuousTestingSupported;
}
}
2 changes: 2 additions & 0 deletions devtools/maven/src/main/java/io/quarkus/maven/TestMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.ResolutionScope;

import io.quarkus.bootstrap.app.QuarkusBootstrap;
import io.quarkus.deployment.dev.DevModeContext;
import io.quarkus.deployment.dev.IsolatedTestModeMain;

Expand All @@ -19,6 +20,7 @@ protected void modifyDevModeContext(MavenDevModeLauncher.Builder builder) {
builder.entryPointCustomizer(new Consumer<DevModeContext>() {
@Override
public void accept(DevModeContext devModeContext) {
devModeContext.setMode(QuarkusBootstrap.Mode.CONTINUOUS_TEST);
devModeContext.setAlternateEntryPoint(IsolatedTestModeMain.class.getName());
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public void setupTestRoutes(
LaunchModeBuildItem launchModeBuildItem,
BuildProducer<RouteBuildItem> routeBuildItemBuildProducer,
BuildProducer<TestListenerBuildItem> testListenerBuildItemBuildProducer) throws IOException {
if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) {
DevModeType devModeType = launchModeBuildItem.getDevModeType().orElse(null);
if (devModeType == null || !devModeType.isContinuousTestingSupported()) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ public enum Mode {
TEST,
PROD,
REMOTE_DEV_SERVER,
REMOTE_DEV_CLIENT;
REMOTE_DEV_CLIENT,
CONTINUOUS_TEST;
}
}

0 comments on commit b97c211

Please sign in to comment.