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

Fix RestAssured URL handling and unexpected restarts in QuarkusProdModeTest #30389

Merged
merged 1 commit into from
Jan 16, 2023
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
5 changes: 5 additions & 0 deletions test-framework/junit5-internal/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ public class QuarkusProdModeTest
private Path logfilePath;
private Optional<Field> logfileField = Optional.empty();
private List<Dependency> forcedDependencies = Collections.emptyList();
private InMemoryLogHandler inMemoryLogHandler = new InMemoryLogHandler((r) -> false);
private InMemoryLogHandler inMemoryLogHandler = new InMemoryLogHandler(r -> false);
private boolean expectExit;
private String startupConsoleOutput;
private Integer exitCode;
private Consumer<Throwable> assertBuildException;
private String[] commandLineParameters = new String[0];

private boolean clearRestAssuredURL;

public QuarkusProdModeTest() {
InputStream appPropsIs = Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties");
if (appPropsIs != null) {
Expand Down Expand Up @@ -620,7 +622,10 @@ public void start() {
.directory(builtResultArtifactParent.toFile())
.start();
ensureApplicationStartupOrFailure();
setupRestAssured();
if (!expectExit) { // no point in setting an URL for an app that exits right away
setupRestAssured();
clearRestAssuredURL = true;
}
} catch (IOException ex) {
throw new RuntimeException("The produced jar could not be launched. ", ex);
}
Expand All @@ -639,6 +644,10 @@ public void stop() {
} catch (InterruptedException ignored) {

}
if (clearRestAssuredURL) {
RestAssuredURLManager.clearURL();
clearRestAssuredURL = false;
}
}

private void setupRestAssured() {
Expand Down Expand Up @@ -725,10 +734,6 @@ public void afterAll(ExtensionContext extensionContext) throws Exception {
rootLogger.setHandlers(originalHandlers);
inMemoryLogHandler.clearRecords();

if (run) {
RestAssuredURLManager.clearURL();
}

stop();

try {
Expand All @@ -753,7 +758,8 @@ public void afterAll(ExtensionContext extensionContext) throws Exception {

@Override
public void beforeEach(ExtensionContext context) {
if (run && (process == null || !process.isAlive())) {
// restart the app in case it was stopped manually via stop() by the previous test method
if (run && !expectExit && (process == null || !process.isAlive())) {
start();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package io.quarkus.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.Mockito;

import io.quarkus.runtime.annotations.QuarkusMain;
import io.quarkus.test.common.RestAssuredURLManager;

@TestMethodOrder(OrderAnnotation.class)
public class QuarkusProdModeTestExpectExitTest {

@RegisterExtension
static final QuarkusProdModeTest simpleApp = new QuarkusProdModeTest()
.withApplicationRoot(jar -> jar.addClass(Main.class))
.setApplicationName("simple-app")
.setApplicationVersion("0.1-SNAPSHOT")
.setExpectExit(true)
.setRun(true);

private static String startupConsoleOutput;

@BeforeAll
static void captureStartupConsoleLog() {
startupConsoleOutput = simpleApp.getStartupConsoleOutput();
assertNotNull(startupConsoleOutput, "Missing startupConsoleOutput");
}

@Test
@Order(1)
public void shouldStartManually() {
thenAppIsNotRunning();
thenAppWasNotRestarted();

try (var urlMgrMock = Mockito.mockStatic(RestAssuredURLManager.class)) {
whenStartApp();
thenAppIsNotRunning();
thenAppWasRestarted();

urlMgrMock.verifyNoInteractions();
}
}

@Test
@Order(2)
public void shouldNotBeRestartedInSubsequentTest() {
thenAppIsNotRunning();
thenAppWasNotRestarted();
}

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

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

private void thenAppWasNotRestarted() {
assertEquals(startupConsoleOutput, simpleApp.getStartupConsoleOutput(), "App was restarted");
}

private void thenAppWasRestarted() {
var newStartupConsoleOutput = simpleApp.getStartupConsoleOutput();
assertNotEquals(startupConsoleOutput, newStartupConsoleOutput, "App was not restarted");
startupConsoleOutput = newStartupConsoleOutput;
}

@QuarkusMain
public static class Main {

public static void main(String[] args) {
System.out.printf("current nano time: %s%n", System.nanoTime());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,49 @@

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.times;

import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.Mockito;

import io.quarkus.test.common.RestAssuredURLManager;

@TestMethodOrder(OrderAnnotation.class)
public class QuarkusProdModeTestTest {

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

@Test
public void shouldStartAndStopInnerProcess() {
@Order(1)
public void shouldStopAndStartManually() {
thenAppIsRunning();

whenStopApp();
thenAppIsNotRunning();
try (var urlMgrMock = Mockito.mockStatic(RestAssuredURLManager.class)) {
whenStopApp();
thenAppIsNotRunning();

whenStartApp();
thenAppIsRunning();

whenStopApp(); // stop again to verify in next test method that app was auto-restarted
thenAppIsNotRunning();

whenStartApp();
urlMgrMock.verify(() -> RestAssuredURLManager.setURL(false, 8081));
urlMgrMock.verify(RestAssuredURLManager::clearURL, times(2));
}
}

@Test
@Order(2)
public void shouldBeStartedAfterPreviousTestStopped() {
thenAppIsRunning();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mock-maker-inline