[강운덕] [PINPOINT-267] ci에서 test를 연속해서 돌릴경우, cl에 이미 로드된 test class를 다시 로드 하는 경우가 발생하여 문제가 생기는 것을 회피하기 위해서 TestClassLoader를 사용하게 함.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@3200 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Woonduk Kang
2014-01-23 10:55:22 +00:00
parent c3be6aa47d
commit 596d2cfe79
4 changed files with 259 additions and 58 deletions
@@ -8,7 +8,7 @@ import java.util.Arrays;
/**
* @author emeroad
*/
public class TestAfterInterceptor implements StaticAroundInterceptor {
public class TestAfterInterceptor implements StaticAroundInterceptor, TargetClassLoader {
private Logger logger = LoggerFactory.getLogger(this.getClass().getName());
public int call = 0;
@@ -9,8 +9,11 @@ import java.util.Arrays;
/**
* @author emeroad
*/
public class TestBeforeInterceptor implements StaticAroundInterceptor {
private Logger logger = LoggerFactory.getLogger(this.getClass().getName());
public class TestBeforeInterceptor implements StaticAroundInterceptor, TargetClassLoader {
static{
System.out.println("load TestBeforeInterceptor cl:" + TestBeforeInterceptor.class.getClassLoader());
}
private Logger logger = LoggerFactory.getLogger(this.getClass().getName());
public int call = 0;
public Object target;
@@ -1,7 +1,16 @@
package com.nhn.pinpoint.profiler.interceptor.bci;
import com.nhn.pinpoint.common.ServiceType;
import com.nhn.pinpoint.profiler.DefaultAgent;
import com.nhn.pinpoint.profiler.DummyInstrumentation;
import com.nhn.pinpoint.profiler.config.ProfilerConfig;
import com.nhn.pinpoint.profiler.interceptor.Interceptor;
import com.nhn.pinpoint.profiler.interceptor.TestAfterInterceptor;
import com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor;
import com.nhn.pinpoint.profiler.logging.PLoggerFactory;
import com.nhn.pinpoint.profiler.logging.Slf4jLoggerBinder;
import com.nhn.pinpoint.profiler.util.TestClassLoader;
import com.nhn.pinpoint.profiler.util.TestModifier;
import javassist.bytecode.Descriptor;
import org.junit.Assert;
import org.junit.Test;
@@ -9,7 +18,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
/**
* @author emeroad
@@ -19,47 +30,132 @@ public class JavaAssistClassTest {
@Test
public void testBeforeAddInterceptor() throws Exception {
final TestClassLoader loader = getTestClassLoader();
final String javassistClassName = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject";
ByteCodeInstrumentor javaAssistByteCodeInstrumentor = new JavaAssistByteCodeInstrumentor();
InstrumentClass aClass = javaAssistByteCodeInstrumentor.getClass("com.nhn.pinpoint.profiler.interceptor.bci.TestObject");
final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) {
TestBeforeInterceptor interceptor = new TestBeforeInterceptor();
String methodName = "callA";
@Override
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
try {
logger.info("modify cl:{}", classLoader);
aClass.addInterceptor(methodName, null, interceptor);
InstrumentClass aClass = byteCodeInstrumentor.getClass(javassistClassName);
Object testObject = createInstance(aClass);
Method callA = testObject.getClass().getMethod(methodName);
interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor");
logger.info(this.interceptor.getClass().getClassLoader().toString());
String methodName = "callA";
aClass.addInterceptor(methodName, null, (Interceptor) interceptor);
return aClass.toBytecode();
} catch (InstrumentException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public Object getInterceptor() {
return interceptor;
}
};
testModifier.setTargetClass(javassistClassName);
loader.addModifier(testModifier);
loader.initialize();
Class testObjectClazz = loader.loadClass(javassistClassName);
final String methodName = "callA";
logger.info("class:{}", testObjectClazz.toString());
final Object testObject = testObjectClazz.newInstance();
Method callA = testObjectClazz.getMethod(methodName);
callA.invoke(testObject);
Assert.assertEquals(interceptor.call, 1);
Assert.assertEquals(interceptor.className, "com.nhn.pinpoint.profiler.interceptor.bci.TestObject");
Assert.assertEquals(interceptor.methodName, methodName);
Assert.assertEquals(interceptor.args, null);
Assert.assertEquals(interceptor.target, testObject);
Object interceptor = testModifier.getInterceptor();
assertEqualsIntField(interceptor, "call", 1);
assertEqualsObjectField(interceptor, "className", "com.nhn.pinpoint.profiler.interceptor.bci.TestObject");
assertEqualsObjectField(interceptor, "methodName", methodName);
assertEqualsObjectField(interceptor, "args", null);
assertEqualsObjectField(interceptor, "target", testObject);
}
private TestClassLoader getTestClassLoader() {
System.setProperty("catalina.home", "test");
PLoggerFactory.initialize(new Slf4jLoggerBinder());
ProfilerConfig profilerConfig = new ProfilerConfig();
profilerConfig.setApplicationServerType(ServiceType.STAND_ALONE);
DefaultAgent agent = new DefaultAgent("", new DummyInstrumentation(), profilerConfig);
return new TestClassLoader(agent);
}
public void assertEqualsIntField(Object target, String fieldName, int value) throws NoSuchFieldException, IllegalAccessException {
Field field = target.getClass().getField(fieldName);
int anInt = field.getInt(target);
Assert.assertEquals(anInt, value);
}
public void assertEqualsObjectField(Object target, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Field field = target.getClass().getField(fieldName);
Object obj = field.get(target);
Assert.assertEquals(obj, value);
}
@Test
public void testBeforeAddInterceptorFormContextClassLoader() throws Exception {
final TestClassLoader loader = getTestClassLoader();
final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader";
final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) {
ByteCodeInstrumentor javaAssistByteCodeInstrumentor = new JavaAssistByteCodeInstrumentor();
InstrumentClass aClass = javaAssistByteCodeInstrumentor.getClass("com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader");
@Override
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
try {
logger.info("modify cl:{}", classLoader);
InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject);
TestBeforeInterceptor interceptor = new TestBeforeInterceptor();
String methodName = "callA";
interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestBeforeInterceptor");
logger.info(this.interceptor.getClass().getClassLoader().toString());
String methodName = "callA";
aClass.addInterceptor(methodName, null, (Interceptor) interceptor);
return aClass.toBytecode();
} catch (InstrumentException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
aClass.addInterceptorCallByContextClassLoader(methodName, null, interceptor);
@Override
public Object getInterceptor() {
return interceptor;
}
};
testModifier.setTargetClass(testClassObject);
loader.addModifier(testModifier);
loader.initialize();
Object testObject = createInstance(aClass);
Method callA = testObject.getClass().getMethod(methodName);
Class testObjectClazz = loader.loadClass("com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader");
final String methodName = "callA";
logger.info("class:{}", testObjectClazz.toString());
final Object testObject = testObjectClazz.newInstance();
Method callA = testObjectClazz.getMethod(methodName);
callA.invoke(testObject);
Assert.assertEquals(interceptor.call, 1);
Assert.assertEquals(interceptor.className, "com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader");
Assert.assertEquals(interceptor.methodName, methodName);
Assert.assertEquals(interceptor.args, null);
Assert.assertEquals(interceptor.target, testObject);
Object interceptor = testModifier.getInterceptor();
assertEqualsIntField(interceptor, "call", 1);
assertEqualsObjectField(interceptor, "className", "com.nhn.pinpoint.profiler.interceptor.bci.TestObjectContextClassLoader");
assertEqualsObjectField(interceptor, "methodName", methodName);
assertEqualsObjectField(interceptor, "args", null);
assertEqualsObjectField(interceptor, "target", testObject);
}
@@ -67,39 +163,73 @@ public class JavaAssistClassTest {
public void testAddAfterInterceptor() throws Exception {
// TODO aClass.addInterceptorCallByContextClassLoader 코드의 테스트 케이스도 추가해야함.
ByteCodeInstrumentor javaAssistByteCodeInstrumentor = new JavaAssistByteCodeInstrumentor();
InstrumentClass aClass = javaAssistByteCodeInstrumentor.getClass("com.nhn.pinpoint.profiler.interceptor.bci.TestObject2");
TestAfterInterceptor callaInterceptor = new TestAfterInterceptor();
String callA = "callA";
aClass.addInterceptor(callA, null, callaInterceptor);
final TestClassLoader loader = getTestClassLoader();
final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestObject2";
final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) {
// return type void test
TestAfterInterceptor callbInterceptor = new TestAfterInterceptor();
String callB = "callB";
aClass.addInterceptor(callB, null, callbInterceptor);
@Override
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
try {
logger.info("modify cl:{}", classLoader);
InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject);
interceptor = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestAfterInterceptor");
logger.info(this.interceptor.getClass().getClassLoader().toString());
String methodName = "callA";
aClass.addInterceptor(methodName, null, (Interceptor) interceptor);
interceptor2 = byteCodeInstrumentor.newInterceptor(classLoader, protectedDomain, "com.nhn.pinpoint.profiler.interceptor.TestAfterInterceptor");
String methodName2 = "callB";
aClass.addInterceptor(methodName2, null, (Interceptor) interceptor2);
return aClass.toBytecode();
} catch (InstrumentException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public Object getInterceptor() {
return interceptor;
}
};
testModifier.setTargetClass(testClassObject);
loader.addModifier(testModifier);
loader.initialize();
Object testObject = createInstance(aClass);
Method callAMethod = testObject.getClass().getMethod(callA);
Object result = callAMethod.invoke(testObject);
Assert.assertEquals(callaInterceptor.call, 1);
Assert.assertEquals(callaInterceptor.className, "com.nhn.pinpoint.profiler.interceptor.bci.TestObject2");
Assert.assertEquals(callaInterceptor.methodName, callA);
Assert.assertNull(callaInterceptor.args);
Assert.assertEquals(callaInterceptor.target, testObject);
Assert.assertEquals(callaInterceptor.result, result);
Class testObjectClazz = loader.loadClass(testClassObject);
final String methodName = "callA";
logger.info("class:{}", testObjectClazz.toString());
final Object testObject = testObjectClazz.newInstance();
Method callA = testObjectClazz.getMethod(methodName);
Object result = callA.invoke(testObject);
Method callBMethod = testObject.getClass().getMethod(callB);
Object interceptor = testModifier.getInterceptor();
assertEqualsIntField(interceptor, "call", 1);
assertEqualsObjectField(interceptor, "className", testClassObject);
assertEqualsObjectField(interceptor, "methodName", methodName);
assertEqualsObjectField(interceptor, "args", null);
assertEqualsObjectField(interceptor, "target", testObject);
assertEqualsObjectField(interceptor, "result", result);
final String methodName2 = "callB";
Method callBMethod = testObject.getClass().getMethod(methodName2);
callBMethod.invoke(testObject);
Assert.assertEquals(callbInterceptor.call, 1);
Assert.assertEquals(callbInterceptor.className, "com.nhn.pinpoint.profiler.interceptor.bci.TestObject2");
Assert.assertEquals(callbInterceptor.methodName, callB);
Assert.assertNull(callbInterceptor.args);
Assert.assertEquals(callbInterceptor.target, testObject);
Assert.assertNull(callbInterceptor.result);
Object interceptor2 = testModifier.getInterceptor2();
assertEqualsIntField(interceptor2, "call", 1);
assertEqualsObjectField(interceptor2, "className", testClassObject);
assertEqualsObjectField(interceptor2, "methodName", methodName2);
assertEqualsObjectField(interceptor2, "args", null);
assertEqualsObjectField(interceptor2, "target", testObject);
assertEqualsObjectField(interceptor2, "result", null);
}
@@ -111,14 +241,38 @@ public class JavaAssistClassTest {
@Test
public void testLog() throws Exception {
ByteCodeInstrumentor javaAssistByteCodeInstrumentor = new JavaAssistByteCodeInstrumentor();
InstrumentClass aClass = javaAssistByteCodeInstrumentor.getClass("com.nhn.pinpoint.profiler.interceptor.bci.TestLog");
aClass.addDebugLogBeforeAfterMethod();
aClass.addDebugLogBeforeAfterConstructor();
final TestClassLoader loader = getTestClassLoader();
final String testClassObject = "com.nhn.pinpoint.profiler.interceptor.bci.TestLog";
final TestModifier testModifier = new TestModifier(loader.getInstrumentor(), loader.getAgent()) {
@Override
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
try {
logger.info("modify cl:{}", classLoader);
InstrumentClass aClass = byteCodeInstrumentor.getClass(testClassObject);
aClass.addDebugLogBeforeAfterMethod();
aClass.addDebugLogBeforeAfterConstructor();
return aClass.toBytecode();
} catch (InstrumentException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public Object getInterceptor() {
return interceptor;
}
};
testModifier.setTargetClass(testClassObject);
loader.addModifier(testModifier);
loader.initialize();
Object testObject = createInstance(aClass);
Object testObject = loader.loadClass(testClassObject).newInstance();
Method test = testObject.getClass().getMethod("test", null);
test.invoke(testObject);
@@ -0,0 +1,44 @@
package com.nhn.pinpoint.profiler.util;
import com.nhn.pinpoint.profiler.Agent;
import com.nhn.pinpoint.profiler.interceptor.bci.ByteCodeInstrumentor;
import com.nhn.pinpoint.profiler.modifier.AbstractModifier;
import java.security.ProtectionDomain;
/**
* @author emeroad
*/
public abstract class TestModifier extends AbstractModifier {
private String targetClass;
public Object interceptor;
public Object interceptor2;
public TestModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
super(byteCodeInstrumentor, agent);
}
public void setTargetClass(String targetClass) {
this.targetClass = targetClass;
}
@Override
public String getTargetClass() {
return targetClass;
}
public Object getInterceptor() {
return interceptor;
}
public Object getInterceptor2() {
return interceptor2;
}
@Override
public abstract byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer);
}