do omni transform

This commit is contained in:
金戟 2021-03-17 14:24:16 +08:00
parent 328296ae3a
commit 7857782125
7 changed files with 42 additions and 8 deletions

View File

@ -10,13 +10,10 @@ import org.objectweb.asm.tree.ClassNode;
*/
abstract public class BaseClassHandler implements Opcodes {
protected static final String TESTABLE_REF = "__testable";
protected static final String GET_TESTABLE_REF = "testableIns";
protected static final String VOID_ARGS = "()";
protected static final String VOID_RES = "V";
protected String mockClassName;
public byte[] getBytes(byte[] classFileBuffer) {
ClassReader cr = new ClassReader(classFileBuffer);
ClassNode cn = new ClassNode();

View File

@ -34,6 +34,9 @@ public class MockClassHandler extends BaseClassWithContextHandler {
private static final String METHOD_IS_ASSOCIATED = "isAssociated";
private static final String SIGNATURE_IS_ASSOCIATED = "()Z";
private static final String SELF_REF = "__self";
private static final String TESTABLE_REF = "__testable";
private final String mockClassName;
public MockClassHandler(String className) {
this.mockClassName = className;

View File

@ -0,0 +1,24 @@
package com.alibaba.testable.agent.handler;
import com.alibaba.testable.agent.util.ClassUtil;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR;
/**
* @author flin
*/
public class OmniClassHandler extends BaseClassHandler {
private static final String TYPE_NULL = "com.alibaba.testable.core.model.Null";
@Override
protected void transform(ClassNode cn) {
if ((cn.access & (ACC_ABSTRACT | ACC_SUPER)) == 0) {
cn.methods.add(new MethodNode(ACC_PRIVATE, CONSTRUCTOR,
"(" + ClassUtil.toByteCodeClassName(TYPE_NULL) + ")V", null, null));
}
}
}

View File

@ -21,6 +21,7 @@ import static com.alibaba.testable.core.constant.ConstPool.CONSTRUCTOR;
*/
public class SourceClassHandler extends BaseClassHandler {
private final String mockClassName;
private final List<MethodInfo> injectMethods;
private final Set<Integer> invokeOps = new HashSet<Integer>() {{
add(Opcodes.INVOKEVIRTUAL);

View File

@ -22,6 +22,7 @@ public class TestClassHandler extends BaseClassWithContextHandler {
private static final String DESC_METHOD_CLEAN = "()V";
private static final String THIS = "this";
private final String mockClassName;
private int testCaseCount = 0;
private final Framework[] frameworkClasses = new Framework[] {

View File

@ -2,6 +2,7 @@ package com.alibaba.testable.agent.transformer;
import com.alibaba.testable.agent.constant.ConstPool;
import com.alibaba.testable.agent.handler.MockClassHandler;
import com.alibaba.testable.agent.handler.OmniClassHandler;
import com.alibaba.testable.agent.handler.SourceClassHandler;
import com.alibaba.testable.agent.handler.TestClassHandler;
import com.alibaba.testable.agent.model.MethodInfo;
@ -43,7 +44,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
* Just avoid spend time to scan those surely non-user classes Should keep these lists as tiny as possible
*/
private final String[] BLACKLIST_PREFIXES = new String[] {"jdk/", "java/", "javax/", "sun/", "com/sun/",
"org/apache/maven/", "com/alibaba/testable/", "junit/", "org/junit/", "org/testng/"};
"org/groovy", "org/apache/maven/", "com/alibaba/testable/", "junit/", "org/junit/", "org/testng/"};
public MockClassParser mockClassParser = new MockClassParser();
@ -55,19 +56,19 @@ public class TestableClassTransformer implements ClassFileTransformer {
return null;
}
LogUtil.verbose("Handle class: " + className);
byte[] bytes = null;
byte[] bytes = new OmniClassHandler().getBytes(classFileBuffer);
try {
if (mockClassParser.isMockClass(className)) {
// it's a mock class
LogUtil.diagnose("Handling mock class %s", className);
bytes = new MockClassHandler(className).getBytes(classFileBuffer);
bytes = new MockClassHandler(className).getBytes(bytes);
dumpByte(className, bytes);
} else {
String mockClass = foundMockForTestClass(className);
if (mockClass != null) {
// it's a test class with testable enabled
LogUtil.diagnose("Handling test class %s", className);
bytes = new TestClassHandler(mockClass).getBytes(classFileBuffer);
bytes = new TestClassHandler(mockClass).getBytes(bytes);
dumpByte(className, bytes);
} else {
mockClass = foundMockForSourceClass(className);
@ -75,7 +76,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
// it's a source class with testable enabled
List<MethodInfo> injectMethods = mockClassParser.getTestableMockMethods(mockClass);
LogUtil.diagnose("Handling source class %s", className);
bytes = new SourceClassHandler(injectMethods, mockClass).getBytes(classFileBuffer);
bytes = new SourceClassHandler(injectMethods, mockClass).getBytes(bytes);
dumpByte(className, bytes);
}
}

View File

@ -0,0 +1,7 @@
package com.alibaba.testable.core.model;
/**
* @author flin
*/
public class Null {
}