code refactor and add test case for util classes

This commit is contained in:
金戟 2020-07-27 20:41:12 +08:00
parent 2f6c2105f6
commit e6ff355da9
17 changed files with 129 additions and 28 deletions

View File

@ -87,7 +87,7 @@ public class SourceClassHandler extends ClassHandler {
List<Byte> parameterTypes = ClassUtil.getParameterTypes(constructorDesc); List<Byte> parameterTypes = ClassUtil.getParameterTypes(constructorDesc);
InsnList il = new InsnList(); InsnList il = new InsnList();
il.add(new MethodInsnNode(INVOKESTATIC, TESTABLE_NE, TESTABLE_W, il.add(new MethodInsnNode(INVOKESTATIC, TESTABLE_NE, TESTABLE_W,
getConstructorSubstitutionDesc(parameterTypes.size()), false)); getConstructorSubstitutionDesc(parameterTypes.size())));
il.add(new TypeInsnNode(CHECKCAST, classType)); il.add(new TypeInsnNode(CHECKCAST, classType));
mn.instructions.insertBefore(instructions[end], il); mn.instructions.insertBefore(instructions[end], il);
mn.instructions.remove(instructions[start]); mn.instructions.remove(instructions[start]);
@ -109,7 +109,7 @@ public class SourceClassHandler extends ClassHandler {
List<Byte> parameterTypes = ClassUtil.getParameterTypes(methodDesc); List<Byte> parameterTypes = ClassUtil.getParameterTypes(methodDesc);
InsnList il = new InsnList(); InsnList il = new InsnList();
il.add(new MethodInsnNode(INVOKESTATIC, TESTABLE_NE, TESTABLE_F, il.add(new MethodInsnNode(INVOKESTATIC, TESTABLE_NE, TESTABLE_F,
getMethodSubstitutionDesc(parameterTypes.size()), false)); getMethodSubstitutionDesc(parameterTypes.size())));
il.add(new TypeInsnNode(CHECKCAST, returnType)); il.add(new TypeInsnNode(CHECKCAST, returnType));
mn.instructions.insertBefore(instructions[end], il); mn.instructions.insertBefore(instructions[end], il);
mn.instructions.remove(instructions[end]); mn.instructions.remove(instructions[end]);

View File

@ -14,6 +14,7 @@ public class TestClassHandler extends ClassHandler {
private static final List<String> TEST_ANNOTATIONS = new ArrayList<String>(); private static final List<String> TEST_ANNOTATIONS = new ArrayList<String>();
private static final String TESTABLE_SETUP_METHOD_NAME = "testableSetup"; private static final String TESTABLE_SETUP_METHOD_NAME = "testableSetup";
private static final String TESTABLE_SETUP_METHOD_DESC = "()V";
static { static {
// JUnit4 // JUnit4
@ -42,7 +43,7 @@ public class TestClassHandler extends ClassHandler {
if (CollectionUtil.containsAny(visibleAnnotationNames, TEST_ANNOTATIONS)) { if (CollectionUtil.containsAny(visibleAnnotationNames, TEST_ANNOTATIONS)) {
InsnList il = new InsnList(); InsnList il = new InsnList();
il.add(new VarInsnNode(ALOAD, 0)); il.add(new VarInsnNode(ALOAD, 0));
il.add(new MethodInsnNode(INVOKESPECIAL, cn.name, TESTABLE_SETUP_METHOD_NAME, "()V", false)); il.add(new MethodInsnNode(INVOKESPECIAL, cn.name, TESTABLE_SETUP_METHOD_NAME, TESTABLE_SETUP_METHOD_DESC));
mn.instructions.insertBefore(mn.instructions.get(0), il); mn.instructions.insertBefore(mn.instructions.get(0), il);
} }
} }

View File

@ -41,7 +41,7 @@ public class ClassUtil {
annotations.add(annotationName); annotations.add(annotationName);
} }
return annotations; return annotations;
} catch (IOException e) { } catch (Exception e) {
return new ArrayList<String>(); return new ArrayList<String>();
} }
} }

View File

@ -1,6 +1,9 @@
package com.alibaba.testable.agent.util; package com.alibaba.testable.agent.util;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List;
/** /**
* @author flin * @author flin
@ -18,4 +21,10 @@ public class CollectionUtil {
return false; return false;
} }
public static <T> List<T> listOf(T... items) {
List<T> list = new ArrayList<T>(items.length);
Collections.addAll(list, items);
return list;
}
} }

View File

@ -6,6 +6,13 @@ import static org.junit.jupiter.api.Assertions.*;
class ClassUtilTest { class ClassUtilTest {
@Test
void should_able_to_get_annotation() {
assertEquals(0, ClassUtil.getAnnotations("class.not.exist").size());
assertEquals(0, ClassUtil.getAnnotations("com.alibaba.testable.agent.util.ClassUtil").size());
assertEquals("org.apiguardian.api.API", ClassUtil.getAnnotations("org.junit.jupiter.api.Assertions").get(0));
}
@Test @Test
void should_able_to_get_parameter_count() { void should_able_to_get_parameter_count() {
assertEquals(1, ClassUtil.getParameterTypes("(Ljava/lang/String;)V").size()); assertEquals(1, ClassUtil.getParameterTypes("(Ljava/lang/String;)V").size());
@ -23,4 +30,10 @@ class ClassUtilTest {
assertEquals("[Ljava/lang/String;", ClassUtil.getReturnType("(Ljava/lang/String;)[Ljava/lang/String;")); assertEquals("[Ljava/lang/String;", ClassUtil.getReturnType("(Ljava/lang/String;)[Ljava/lang/String;"));
} }
@Test
void should_able_to_convert_class_name() {
assertEquals("Ljava/lang/String;", ClassUtil.toByteCodeClassName("java.lang.String"));
}
} }

View File

@ -0,0 +1,19 @@
package com.alibaba.testable.agent.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CollectionUtilTest {
@Test
void should_able_to_check_collection_contains_any_element() {
assertTrue(CollectionUtil.containsAny(
CollectionUtil.listOf("a", "b"), CollectionUtil.listOf("b", "c")
));
assertFalse(CollectionUtil.containsAny(
CollectionUtil.listOf("a", "b"), CollectionUtil.listOf("c", "d")
));
}
}

View File

@ -0,0 +1,16 @@
package com.alibaba.testable.agent.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class StringUtilTest {
@Test
void should_able_to_repeat_text() {
assertEquals("", StringUtil.repeat("abc", 0));
assertEquals("abc", StringUtil.repeat("abc", 1));
assertEquals("abcabcabc", StringUtil.repeat("abc", 3));
}
}

View File

@ -25,6 +25,12 @@
<scope>system</scope> <scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath> <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -1,4 +1,4 @@
package com.alibaba.testable.core.util; package com.alibaba.testable.core.constant;
/** /**
* @author flin * @author flin

View File

@ -1,7 +1,7 @@
package com.alibaba.testable.core.generator; package com.alibaba.testable.core.generator;
import com.alibaba.testable.core.model.TestableContext; import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.util.ConstPool; import com.alibaba.testable.core.constant.ConstPool;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.ListBuffer;

View File

@ -1,7 +1,7 @@
package com.alibaba.testable.core.generator; package com.alibaba.testable.core.generator;
import com.alibaba.testable.core.model.TestableContext; import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.util.ConstPool; import com.alibaba.testable.core.constant.ConstPool;
import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;

View File

@ -2,7 +2,7 @@ package com.alibaba.testable.core.processor;
import com.alibaba.testable.core.annotation.EnableTestable; import com.alibaba.testable.core.annotation.EnableTestable;
import com.alibaba.testable.core.translator.EnableTestableTranslator; import com.alibaba.testable.core.translator.EnableTestableTranslator;
import com.alibaba.testable.core.util.ConstPool; import com.alibaba.testable.core.constant.ConstPool;
import com.alibaba.testable.core.util.ResourceUtil; import com.alibaba.testable.core.util.ResourceUtil;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
@ -61,7 +61,8 @@ public class EnableTestableProcessor extends BaseProcessor {
} }
private void createTestableAgentJar() { private void createTestableAgentJar() {
if (!checkFirstClassCompiled()) { if (!hasFirstClassCompiled) {
hasFirstClassCompiled = true;
byte[] bytes = ResourceUtil.fetchBinary(TESTABLE_AGENT_JAR); byte[] bytes = ResourceUtil.fetchBinary(TESTABLE_AGENT_JAR);
if (bytes.length == 0) { if (bytes.length == 0) {
cx.logger.error("Failed to generate testable agent jar"); cx.logger.error("Failed to generate testable agent jar");
@ -70,14 +71,6 @@ public class EnableTestableProcessor extends BaseProcessor {
} }
} }
private boolean checkFirstClassCompiled() {
if (!hasFirstClassCompiled) {
hasFirstClassCompiled = true;
return false;
}
return true;
}
private void writeBinaryFile(String path, String fileName, byte[] content) { private void writeBinaryFile(String path, String fileName, byte[] content) {
try { try {
FileObject resource = cx.filter.createResource(StandardLocation.SOURCE_OUTPUT, path, fileName); FileObject resource = cx.filter.createResource(StandardLocation.SOURCE_OUTPUT, path, fileName);

View File

@ -3,10 +3,9 @@ package com.alibaba.testable.core.translator;
import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator; import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator;
import com.alibaba.testable.core.generator.TestSetupMethodGenerator; import com.alibaba.testable.core.generator.TestSetupMethodGenerator;
import com.alibaba.testable.core.model.TestableContext; import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.util.ConstPool; import com.alibaba.testable.core.constant.ConstPool;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Pair; import com.sun.tools.javac.util.Pair;

View File

@ -3,14 +3,12 @@ package com.alibaba.testable.core.util;
import java.io.*; import java.io.*;
/** /**
* Generate global n.e class code
*
* @author flin * @author flin
*/ */
public class ResourceUtil { public class ResourceUtil {
public static String fetchText(String fileName) { public static String fetchText(String filePath) {
InputStream in = ResourceUtil.class.getResourceAsStream("/" + fileName); InputStream in = ResourceUtil.class.getResourceAsStream("/" + filePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(in)); BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
String line; String line;
@ -22,15 +20,15 @@ public class ResourceUtil {
reader.close(); reader.close();
return buffer.toString(); return buffer.toString();
} catch (IOException e) { } catch (IOException e) {
System.err.println("Failed to fetch text file: " + fileName); System.err.println("Failed to fetch text file: " + filePath);
return ""; return "";
} }
} }
public static byte[] fetchBinary(String fileName) { public static byte[] fetchBinary(String filePath) {
InputStream in = ResourceUtil.class.getResourceAsStream("/" + fileName); InputStream in = ResourceUtil.class.getResourceAsStream("/" + filePath);
if (in == null) { if (in == null) {
System.err.println("Resource " + fileName + " not exist"); System.err.println("Resource " + filePath + " not exist");
return new byte[] {}; return new byte[] {};
} }
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@ -44,7 +42,7 @@ public class ResourceUtil {
buffer.close(); buffer.close();
return buffer.toByteArray(); return buffer.toByteArray();
} catch (IOException e) { } catch (IOException e) {
System.err.println("Failed to fetch file: " + fileName); System.err.println("Failed to fetch file: " + filePath);
return new byte[] {}; return new byte[] {};
} }
} }

View File

@ -2,6 +2,9 @@ package com.alibaba.testable.core.util;
import java.util.List; import java.util.List;
/**
* @author flin
*/
public class StringUtil { public class StringUtil {
static public String join(List<String> list, String conjunction) static public String join(List<String> list, String conjunction)

View File

@ -0,0 +1,23 @@
package com.alibaba.testable.core.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ResourceUtilTest {
@Test
void fetchText() {
assertTrue(
ResourceUtil.fetchText("META-INF/services/javax.annotation.processing.Processor").startsWith("com.")
);
}
@Test
void should_able_to_fetch_binary() {
assertTrue(
ResourceUtil.fetchBinary("com/alibaba/testable/core/util/ResourceUtil.class").length > 0
);
}
}

View File

@ -0,0 +1,21 @@
package com.alibaba.testable.core.util;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class StringUtilTest {
@Test
void should_able_to_join_string() {
List<String> list = new ArrayList<>(4);
list.add("a");
list.add("b");
list.add("c");
list.add("d");
assertEquals("a-b-c-d", StringUtil.join(list, "-"));
}
}