mirror of
https://github.com/jlengrand/quarkus.git
synced 2026-03-10 08:41:22 +00:00
Make sure that src/test/resources takes precidence for @QuarkusTest
This allows for easy config overriding in tests
This commit is contained in:
@@ -30,10 +30,21 @@ public class AdditionalDependency implements Serializable {
|
||||
*/
|
||||
private final boolean forceApplicationArchive;
|
||||
|
||||
/**
|
||||
* If this dep is the test classes directory. If so then this will have precedence over the application
|
||||
*/
|
||||
private final boolean testClassRoot;
|
||||
|
||||
public AdditionalDependency(Path archivePath, boolean hotReloadable, boolean forceApplicationArchive) {
|
||||
this(archivePath, hotReloadable, forceApplicationArchive, false);
|
||||
}
|
||||
|
||||
public AdditionalDependency(Path archivePath, boolean hotReloadable, boolean forceApplicationArchive,
|
||||
boolean testClassRoot) {
|
||||
this.archivePath = archivePath;
|
||||
this.hotReloadable = hotReloadable;
|
||||
this.forceApplicationArchive = forceApplicationArchive;
|
||||
this.testClassRoot = testClassRoot;
|
||||
}
|
||||
|
||||
public Path getArchivePath() {
|
||||
@@ -47,4 +58,8 @@ public class AdditionalDependency implements Serializable {
|
||||
public boolean isForceApplicationArchive() {
|
||||
return forceApplicationArchive;
|
||||
}
|
||||
|
||||
public boolean isTestClassRoot() {
|
||||
return testClassRoot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.quarkus.bootstrap.app;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -113,7 +112,8 @@ public class CuratedApplication implements Serializable, Closeable {
|
||||
public AugmentAction createAugmentor(String functionName, Map<String, Object> props) {
|
||||
try {
|
||||
Class<?> augmentor = getAugmentClassLoader().loadClass(AUGMENTOR);
|
||||
Function<Object, List<?>> function = (Function<Object, List<?>>) getAugmentClassLoader().loadClass(functionName).newInstance();
|
||||
Function<Object, List<?>> function = (Function<Object, List<?>>) getAugmentClassLoader().loadClass(functionName)
|
||||
.newInstance();
|
||||
List<?> res = function.apply(props);
|
||||
return (AugmentAction) augmentor.getConstructor(CuratedApplication.class, List.class).newInstance(this, res);
|
||||
} catch (Exception e) {
|
||||
@@ -224,18 +224,27 @@ public class CuratedApplication implements Serializable, Closeable {
|
||||
QuarkusClassLoader.Builder builder = QuarkusClassLoader.builder("Quarkus Base Runtime ClassLoader",
|
||||
quarkusBootstrap.getBaseClassLoader(), false);
|
||||
if (quarkusBootstrap.getMode() == QuarkusBootstrap.Mode.TEST) {
|
||||
|
||||
//in test mode we have everything in the base class loader
|
||||
//there is no need to restart so there is no need for an additional CL
|
||||
|
||||
for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) {
|
||||
//src/test is the highest priority
|
||||
if (i.isTestClassRoot()) {
|
||||
builder.addElement(ClassPathElement.fromPath(i.getArchivePath()));
|
||||
}
|
||||
}
|
||||
|
||||
builder.addElement(ClassPathElement.fromPath(getQuarkusBootstrap().getApplicationRoot()));
|
||||
}
|
||||
//additional user class path elements first
|
||||
Set<Path> hotReloadPaths = new HashSet<>();
|
||||
for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) {
|
||||
if (!i.isHotReloadable()) {
|
||||
builder.addElement(ClassPathElement.fromPath(i.getArchivePath()));
|
||||
} else {
|
||||
hotReloadPaths.add(i.getArchivePath());
|
||||
if (!i.isTestClassRoot()) {
|
||||
if (!i.isHotReloadable()) {
|
||||
builder.addElement(ClassPathElement.fromPath(i.getArchivePath()));
|
||||
} else {
|
||||
hotReloadPaths.add(i.getArchivePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.setResettableElement(new MemoryClassPathElement(Collections.emptyMap()));
|
||||
@@ -264,20 +273,26 @@ public class CuratedApplication implements Serializable, Closeable {
|
||||
QuarkusClassLoader.Builder builder = QuarkusClassLoader.builder("Deployment Class Loader",
|
||||
getAugmentClassLoader(), false)
|
||||
.setAggregateParentResources(true);
|
||||
//add the application root
|
||||
//add the application root, and test roots
|
||||
for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) {
|
||||
if (i.isTestClassRoot()) {
|
||||
builder.addElement(ClassPathElement.fromPath(i.getArchivePath()));
|
||||
}
|
||||
}
|
||||
builder.addElement(ClassPathElement.fromPath(quarkusBootstrap.getApplicationRoot()));
|
||||
|
||||
//additional user class path elements first
|
||||
for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) {
|
||||
builder.addElement(ClassPathElement.fromPath(i.getArchivePath()));
|
||||
if (!i.isTestClassRoot()) {
|
||||
builder.addElement(ClassPathElement.fromPath(i.getArchivePath()));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
public QuarkusClassLoader createRuntimeClassLoader(QuarkusClassLoader loader,
|
||||
Map<String, List<BiFunction<String, ClassVisitor, ClassVisitor>>> bytecodeTransformers,
|
||||
ClassLoader deploymentClassLoader, Map<String, byte[]> resources) {
|
||||
Map<String, List<BiFunction<String, ClassVisitor, ClassVisitor>>> bytecodeTransformers,
|
||||
ClassLoader deploymentClassLoader, Map<String, byte[]> resources) {
|
||||
QuarkusClassLoader.Builder builder = QuarkusClassLoader.builder("Quarkus Runtime ClassLoader",
|
||||
loader, false)
|
||||
.setAggregateParentResources(true);
|
||||
@@ -296,10 +311,10 @@ public class CuratedApplication implements Serializable, Closeable {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if(augmentClassLoader != null) {
|
||||
if (augmentClassLoader != null) {
|
||||
augmentClassLoader.close();
|
||||
}
|
||||
if(baseRuntimeClassLoader != null) {
|
||||
if (baseRuntimeClassLoader != null) {
|
||||
baseRuntimeClassLoader.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.quarkus.it.resteasy.jackson;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
|
||||
@Path("/message")
|
||||
public class MessageResource {
|
||||
|
||||
@ConfigProperty(name = "message")
|
||||
String message;
|
||||
|
||||
@GET
|
||||
public String message() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
message=Production
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.quarkus.it.resteasy.jackson;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.quarkus.test.junit.NativeImageTest;
|
||||
|
||||
/**
|
||||
* tests that application.properties is read from src/main/resources when running native image tests
|
||||
*
|
||||
* This does not necessarily belong here, but main and test-extension have a lot of existing
|
||||
* config that would need to be duplicated, so it is here out of convenience.
|
||||
*/
|
||||
@NativeImageTest
|
||||
class ApplicationPropertiesOverrideIT {
|
||||
|
||||
@Test
|
||||
void testEndpoint() {
|
||||
given()
|
||||
.when().get("/message")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body(containsString("Production"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.quarkus.it.resteasy.jackson;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
|
||||
/**
|
||||
* tests that application.properties is read from src/test/resources
|
||||
*
|
||||
* This does not necessarily belong here, but main and test-extension have a lot of existing
|
||||
* config that would need to be duplicated, so it is here out of convenience.
|
||||
*/
|
||||
@QuarkusTest
|
||||
class ApplicationPropertiesOverrideTest {
|
||||
|
||||
@Test
|
||||
void testEndpoint() {
|
||||
given()
|
||||
.when().get("/message")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body(containsString("Test"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
message=Test
|
||||
@@ -80,7 +80,7 @@ public class QuarkusTestExtension
|
||||
testClassLocation = getTestClassesLocation(context.getRequiredTestClass());
|
||||
|
||||
if (!appClassLocation.equals(testClassLocation)) {
|
||||
runnerBuilder.addAdditionalApplicationArchive(new AdditionalDependency(testClassLocation, false, true));
|
||||
runnerBuilder.addAdditionalApplicationArchive(new AdditionalDependency(testClassLocation, false, true, true));
|
||||
}
|
||||
CuratedApplication curatedApplication = runnerBuilder
|
||||
.setTest(true)
|
||||
@@ -171,7 +171,7 @@ public class QuarkusTestExtension
|
||||
ExtensionContext root = extensionContext.getRoot();
|
||||
ExtensionContext.Store store = root.getStore(ExtensionContext.Namespace.GLOBAL);
|
||||
ExtensionState state = store.get(ExtensionState.class.getName(), ExtensionState.class);
|
||||
if (state == null) {
|
||||
if (state == null && !failedBoot) {
|
||||
PropertyTestUtil.setLogFileProperty();
|
||||
TestResourceManager testResourceManager = new TestResourceManager(extensionContext.getRequiredTestClass());
|
||||
try {
|
||||
@@ -261,6 +261,9 @@ public class QuarkusTestExtension
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
ExtensionState state = ensureStarted(extensionContext);
|
||||
if (failedBoot) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
initTestState(extensionContext, state);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user