Assert no bootstrap classes in test fields or method signatures

This commit is contained in:
Andrew Kent 2018-10-11 19:49:40 -07:00
parent 13c96bba33
commit a697881efb
2 changed files with 37 additions and 12 deletions

View File

@ -4,6 +4,7 @@ import com.google.common.reflect.ClassPath;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -66,6 +67,7 @@ public class SpockRunner extends Sputnik {
throws InitializationError, NoSuchFieldException, SecurityException, IllegalArgumentException, throws InitializationError, NoSuchFieldException, SecurityException, IllegalArgumentException,
IllegalAccessException { IllegalAccessException {
super(shadowTestClass(clazz)); super(shadowTestClass(clazz));
assertNoBootstrapClassesInTestClass(clazz);
// access the classloader created in shadowTestClass above // access the classloader created in shadowTestClass above
Field clazzField = Sputnik.class.getDeclaredField("clazz"); Field clazzField = Sputnik.class.getDeclaredField("clazz");
try { try {
@ -77,6 +79,37 @@ public class SpockRunner extends Sputnik {
} }
} }
private static void assertNoBootstrapClassesInTestClass(Class<?> testClass) {
for (final Field field : testClass.getDeclaredFields()) {
assertNotBootstrapClass(testClass, field.getType());
}
for (final Method method : testClass.getDeclaredMethods()) {
assertNotBootstrapClass(testClass, method.getReturnType());
for (final Class paramType : method.getParameterTypes()) {
assertNotBootstrapClass(testClass, paramType);
}
}
}
private static void assertNotBootstrapClass(Class<?> testClass, Class<?> clazz) {
if ((!clazz.isPrimitive()) && isBootstrapClass(clazz.getName())) {
throw new IllegalStateException(
testClass.getName()
+ ": Bootstrap classes are not allowed in test class field or method signatures. Offending class: "
+ clazz.getName());
}
}
private static boolean isBootstrapClass(String className) {
for (int i = 0; i < TEST_BOOTSTRAP_PREFIXES.length; ++i) {
if (className.startsWith(TEST_BOOTSTRAP_PREFIXES[i])) {
return true;
}
}
return false;
}
// Shadow the test class with bytes loaded by InstrumentationClassLoader // Shadow the test class with bytes loaded by InstrumentationClassLoader
private static Class<?> shadowTestClass(final Class<?> clazz) { private static Class<?> shadowTestClass(final Class<?> clazz) {
try { try {
@ -117,11 +150,8 @@ public class SpockRunner extends Sputnik {
Set<String> bootstrapClasses = new HashSet<String>(); Set<String> bootstrapClasses = new HashSet<String>();
for (ClassPath.ClassInfo info : TestUtils.getTestClasspath().getAllClasses()) { for (ClassPath.ClassInfo info : TestUtils.getTestClasspath().getAllClasses()) {
// if info starts with bootstrap prefix: add to bootstrap jar // if info starts with bootstrap prefix: add to bootstrap jar
for (int i = 0; i < TEST_BOOTSTRAP_PREFIXES.length; ++i) { if (isBootstrapClass(info.getName())) {
if (info.getName().startsWith(TEST_BOOTSTRAP_PREFIXES[i])) { bootstrapClasses.add(info.getResourceName());
bootstrapClasses.add(info.getResourceName());
break;
}
} }
} }
return new File( return new File(

View File

@ -13,10 +13,6 @@ class AgentTestRunnerTest extends AgentTestRunner {
private static final ClassLoader BOOTSTRAP_CLASSLOADER = null private static final ClassLoader BOOTSTRAP_CLASSLOADER = null
private static final ClassLoader OT_LOADER private static final ClassLoader OT_LOADER
private static final boolean AGENT_INSTALLED_IN_CLINIT private static final boolean AGENT_INSTALLED_IN_CLINIT
// having opentracing class in test field should not cause problems
private static final Tracer A_TRACER = null
// having dd tracer api class in test field should not cause problems
private static final datadog.trace.api.Tracer DD_API_TRACER = null
@Shared @Shared
private Class sharedSpanClass private Class sharedSpanClass
@ -52,10 +48,9 @@ class AgentTestRunnerTest extends AgentTestRunner {
} }
expect: expect:
// a shared OT class should cause no trouble // shared OT classes should cause no trouble
sharedSpanClass.getClassLoader() == BOOTSTRAP_CLASSLOADER sharedSpanClass.getClassLoader() == BOOTSTRAP_CLASSLOADER
A_TRACER == null Tracer.getClassLoader() == BOOTSTRAP_CLASSLOADER
DD_API_TRACER == null
!AGENT_INSTALLED_IN_CLINIT !AGENT_INSTALLED_IN_CLINIT
getTestTracer() == TestUtils.getUnderlyingGlobalTracer() getTestTracer() == TestUtils.getUnderlyingGlobalTracer()
getAgentTransformer() != null getAgentTransformer() != null