Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add QuarkusProdModeTest start/stop methods and fix restassured random port #15073

Merged
merged 1 commit into from
Feb 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public class QuarkusProdModeTest

private Process process;

private Path builtResultArtifact;
private ProdModeTestResults prodModeTestResults;
private Optional<Field> prodModeTestResultsField = Optional.empty();
private Path logfilePath;
Expand All @@ -114,7 +115,7 @@ public class QuarkusProdModeTest
private InMemoryLogHandler inMemoryLogHandler = new InMemoryLogHandler((r) -> false);
private boolean expectExit;
private String startupConsoleOutput;
private int exitCode;
private Integer exitCode;
private Consumer<Throwable> assertBuildException;
private String[] commandLineParameters = new String[0];

Expand Down Expand Up @@ -259,9 +260,10 @@ public String getStartupConsoleOutput() {
}

/**
* Returns the process exit code, this can only be used if {@link #expectExit} is true
* Returns the process exit code, this can only be used if {@link #expectExit} is true.
* Null if the app is running.
*/
public int getExitCode() {
public Integer getExitCode() {
return exitCode;
}

Expand Down Expand Up @@ -401,14 +403,10 @@ public void close() throws Throwable {
curatedApplication.close();
}

Path builtResultArtifact = setupProdModeResults(testClass, buildDir, result);
builtResultArtifact = setupProdModeResults(testClass, buildDir, result);

if (run) {
startBuiltResult(builtResultArtifact);
RestAssuredURLManager.setURL(false,
runtimeProperties.get(QUARKUS_HTTP_PORT_PROPERTY) != null
? Integer.parseInt(runtimeProperties.get(QUARKUS_HTTP_PORT_PROPERTY))
: DEFAULT_HTTP_PORT_INT);
start();

if (logfilePath != null) {
logfileField = Arrays.stream(testClass.getDeclaredFields()).filter(
Expand Down Expand Up @@ -465,8 +463,20 @@ private Path setupProdModeResults(Class<?> testClass, Path buildDir, AugmentResu
return builtResultArtifact;
}

private void startBuiltResult(Path builtResultArtifact) throws IOException {
Path builtResultArtifactParentDir = builtResultArtifact.getParent();
/**
* Start the Quarkus application. If the application is already started, it raises an {@link IllegalStateException}
* exception.
*
* @throws RuntimeException when application errors at startup.
* @throws IllegalStateException if the application is already started.
*/
public void start() {
if (process != null && process.isAlive()) {
throw new IllegalStateException("Quarkus application is already started. ");
}

exitCode = null;
Path builtResultArtifactParent = builtResultArtifact.getParent();

if (runtimeProperties == null) {
runtimeProperties = new HashMap<>();
Expand All @@ -476,7 +486,7 @@ private void startBuiltResult(Path builtResultArtifact) throws IOException {
}
runtimeProperties.putIfAbsent(QUARKUS_HTTP_PORT_PROPERTY, DEFAULT_HTTP_PORT);
if (logFileName != null) {
logfilePath = builtResultArtifactParentDir.resolve(logFileName);
logfilePath = builtResultArtifactParent.resolve(logFileName);
runtimeProperties.put("quarkus.log.file.path", logfilePath.toAbsolutePath().toString());
runtimeProperties.put("quarkus.log.file.enable", "true");
}
Expand Down Expand Up @@ -505,11 +515,46 @@ private void startBuiltResult(Path builtResultArtifact) throws IOException {
}

command.addAll(Arrays.asList(commandLineParameters));
process = new ProcessBuilder(command)
.redirectErrorStream(true)
.directory(builtResultArtifactParentDir.toFile())
.start();
ensureApplicationStartupOrFailure();

try {
process = new ProcessBuilder(command)
.redirectErrorStream(true)
.directory(builtResultArtifactParent.toFile())
.start();
ensureApplicationStartupOrFailure();
setupRestAssured();
} catch (IOException ex) {
throw new RuntimeException("The produced jar could not be launched. ", ex);
}
}

/**
* Stop the Quarkus application.
*/
public void stop() {
try {
if (process != null) {
process.destroy();
process.waitFor();
exitCode = process.exitValue();
}
} catch (InterruptedException ignored) {

}
}

private void setupRestAssured() {
Integer httpPort = Optional.ofNullable(runtimeProperties.get(QUARKUS_HTTP_PORT_PROPERTY))
.map(Integer::parseInt)
.orElse(DEFAULT_HTTP_PORT_INT);

// If http port is 0, then we need to set the port to null in order to use the `quarkus.https.test-port` property
// which is done in `RestAssuredURLManager.setURL`.
if (httpPort == 0) {
httpPort = null;
}

RestAssuredURLManager.setURL(false, httpPort);
}

private void ensureApplicationStartupOrFailure() throws IOException {
Expand Down Expand Up @@ -586,14 +631,7 @@ public void afterAll(ExtensionContext extensionContext) throws Exception {
RestAssuredURLManager.clearURL();
}

try {
if (process != null) {
process.destroy();
process.waitFor();
}
} catch (InterruptedException ignored) {

}
stop();

try {
if (curatedApplication != null) {
Expand All @@ -611,6 +649,10 @@ public void afterAll(ExtensionContext extensionContext) throws Exception {

@Override
public void beforeEach(ExtensionContext context) {
if (run && (process == null || !process.isAlive())) {
start();
}

prodModeTestResultsField.ifPresent(f -> {
try {
f.set(context.getRequiredTestInstance(), prodModeTestResults);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.quarkus.test;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

public class QuarkusProdModeTestTest {
@RegisterExtension
static final QuarkusProdModeTest simpleApp = new QuarkusProdModeTest()
.setApplicationName("simple-app")
.setApplicationVersion("0.1-SNAPSHOT")
.setRun(true);

@Test
public void shouldStartAndStopInnerProcess() {
thenAppIsRunning();

whenStopApp();
thenAppIsNotRunning();

whenStartApp();
thenAppIsRunning();
}

private void whenStopApp() {
simpleApp.stop();
}

private void whenStartApp() {
simpleApp.start();
}

private void thenAppIsNotRunning() {
assertNotNull(simpleApp.getExitCode(), "App is running");
}

private void thenAppIsRunning() {
assertNull(simpleApp.getExitCode(), "App is not running");
}
}