Skip to content

Commit

Permalink
Add ability to control which classes are cloned
Browse files Browse the repository at this point in the history
This can interfere with other JUnit exists, such
as Pact.

Also make Pact parent first.

Fixes #9677
  • Loading branch information
stuartwdouglas committed May 19, 2021
1 parent e982294 commit 9102276
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ public class TestConfig {
@ConfigItem(defaultValue = "all")
TestType type;

/**
* If a class matches this pattern then it will be cloned into the Quarkus ClassLoader even if it
* is in a parent first artifact.
*
* This is important for collections which can contain objects from the Quarkus ClassLoader, but for
* most parent first classes it will just cause problems.
*/
@ConfigItem(defaultValue = "java\\..*")
String classClonePattern;

@ConfigGroup
public static class Profile {

Expand Down
11 changes: 11 additions & 0 deletions core/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,17 @@
<parentFirstArtifact>org.opentest4j:opentest4j</parentFirstArtifact>
<parentFirstArtifact>org.junit.platform:junit-platform-commons</parentFirstArtifact>

<!-- Pact support. It would be great if there was somewhere better to put this-->
<parentFirstArtifact>au.com.dius:pact-jvm-provider-junit5</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-provider</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-core-support</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-core-pact-broker</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-core-model</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-core-matchers</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-junit5</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-consumer-java8</parentFirstArtifact>
<parentFirstArtifact>au.com.dius:pact-jvm-consumer</parentFirstArtifact>

</parentFirstArtifacts>
<runnerParentFirstArtifacts>
<runnerParentFirstArtifact>org.graalvm.sdk:graal-sdk</runnerParentFirstArtifact>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.enterprise.inject.Alternative;
Expand Down Expand Up @@ -127,6 +129,7 @@ public class QuarkusTestExtension
private static Object actualTestInstance;
private static ClassLoader originalCl;
private static RunningQuarkusApplication runningQuarkusApplication;
private static Pattern clonePattern;
private static Throwable firstException; //if this is set then it will be thrown from the very first test that is run, the rest are aborted

private static List<Object> beforeClassCallbacks;
Expand Down Expand Up @@ -343,6 +346,9 @@ private ExtensionState doJavaStart(ExtensionContext context, Class<? extends Qua
populateCallbacks(startupAction.getClassLoader());

runningQuarkusApplication = startupAction.run();
String patternString = runningQuarkusApplication.getConfigValue("quarkus.test.class-clone-pattern", String.class)
.orElse("java\\..*");
clonePattern = Pattern.compile(patternString);
TracingHandler.quarkusStarted();

//now we have full config reset the hang timer
Expand Down Expand Up @@ -951,7 +957,36 @@ private Object runExtensionMethod(ReflectiveInvocationContext<Method> invocation
List<Object> originalArguments = invocationContext.getArguments();
List<Object> argumentsFromTccl = new ArrayList<>();
for (Object arg : originalArguments) {
argumentsFromTccl.add(deepClone.clone(arg));
boolean cloneRequired = false;
if (arg != null) {
Class theclass = arg.getClass();
while (theclass.isArray()) {
theclass = theclass.getComponentType();
}
String className = theclass.getName();
if (theclass.isPrimitive()) {
cloneRequired = false;
} else if (clonePattern.matcher(className).matches()) {
cloneRequired = true;
} else {
try {
cloneRequired = runningQuarkusApplication.getClassLoader()
.loadClass(theclass.getName()) != theclass;
} catch (ClassNotFoundException e) {
if (arg instanceof Supplier) {
cloneRequired = true;
} else {
throw e;
}
}
}
}

if (cloneRequired) {
argumentsFromTccl.add(deepClone.clone(arg));
} else {
argumentsFromTccl.add(arg);
}
}

return newMethod.invoke(actualTestInstance, argumentsFromTccl.toArray(new Object[0]));
Expand Down Expand Up @@ -1087,6 +1122,7 @@ public void close() {
log.error("Failed to shutdown Quarkus", e);
} finally {
runningQuarkusApplication = null;
clonePattern = null;
try {
if (QuarkusTestExtension.this.originalCl != null) {
setCCL(QuarkusTestExtension.this.originalCl);
Expand Down

0 comments on commit 9102276

Please sign in to comment.