package nginx.clojure.wave;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import nginx.clojure.asm.Type;
import nginx.clojure.wave.MethodDatabase;
import nginx.clojure.wave.MethodDatabase.ClassEntry;
import nginx.clojure.wave.MethodDatabaseUtil;
import org.junit.Test;
import clojure.lang.AFunction;
public class MethodDatabaseUtilTest {
@Test
public void testLoad() throws IOException {
MethodDatabase db = new MethodDatabase(Thread.currentThread().getContextClassLoader());
MethodDatabaseUtil.load(db, "nginx/clojure/wave/test-coroutine-method-db.txt");
ClassEntry ce = db.getClasses().get("java/lang/Thread");
assertEquals(MethodDatabase.SUSPEND_BLOCKING, ce.check("sleep", "(J)V"));
assertEquals(MethodDatabase.SUSPEND_BLOCKING, ce.check("sleep", "(JI)V"));
assertEquals(MethodDatabase.SUSPEND_BLOCKING, ce.check("join", "()V"));
ce = db.getClasses().get("java/lang/Object");
assertEquals(MethodDatabase.SUSPEND_BLOCKING, ce.check("wait", "(J)V"));
assertEquals(MethodDatabase.SUSPEND_BLOCKING, ce.check("wait", "()V"));
assertEquals(MethodDatabase.SUSPEND_BLOCKING, ce.check("wait", "(JI)V"));
assertNull(ce.check("test-unknown-method", "()V"));
ce = db.getClasses().get("clojure/lang/IFn");
assertEquals(MethodDatabase.SUSPEND_FAMILY, ce.check("invoke", "()Ljava/lang/Object;"));
ClassEntry mce = MethodDatabaseUtil.buildClassEntryFamily(db, Type.getInternalName(MyAF.class));
assertEquals(MethodDatabase.SUSPEND_FAMILY, db.checkMethodSuspendType(Type.getInternalName(MyAF.class), "invoke()Ljava/lang/Object;", true));
}
public void testLazyAndFuzzyClass() throws IOException {
MethodDatabase db = new MethodDatabase(Thread.currentThread().getContextClassLoader());
MethodDatabaseUtil.load(db, "nginx/clojure/wave/test-coroutine-and-compojure-db.txt");
ClassEntry sce = MethodDatabaseUtil.buildClassEntryFamily(db, "nginx/clojure/net/SimpleHandler4TestNginxClojureSocket");
assertEquals(MethodDatabase.SUSPEND_NORMAL, sce.check("invoke(Ljava/lang/Object;)Ljava/lang/Object;"));
}
public static class MyAF extends AFunction {
@Override
public Object invoke() {
return super.invoke();
}
}
@Test
public void testBuildClassEntryFamily() throws IOException {
MethodDatabase db = new MethodDatabase(Thread.currentThread().getContextClassLoader());
MethodDatabaseUtil.load(db, "nginx/clojure/wave/coroutine-method-db.txt");
ClassEntry ce = MethodDatabaseUtil.buildClassEntryFamily(db, "nginx/clojure/CatchTest");
assertEquals(MethodDatabase.SUSPEND_NONE, ce.check("testCatch", "()V"));
assertEquals(MethodDatabase.SUSPEND_NORMAL, ce.check("run", "()V"));
ClassEntry ifnce = MethodDatabaseUtil.buildClassEntryFamily(db, Type.getInternalName(MyAF.class));
assertEquals(MethodDatabase.SUSPEND_FAMILY, db.checkMethodSuspendType(Type.getInternalName(MyAF.class),"invoke()Ljava/lang/Object;", true));
}
@Test
public void testMergeExistsDBText() throws Exception {
ConcurrentHashMap<String, ConcurrentHashMap<String, Object>> result = new ConcurrentHashMap<String, ConcurrentHashMap<String, Object>>();
Map<String, TreeMap<String, String>> upperMarks = new TreeMap<String, TreeMap<String, String>>();
SuspendMethodTracer.load(this.getClass().getResourceAsStream("test-merge-exists-db.txt"), result, upperMarks);
assertEquals(2, result.size());
ConcurrentHashMap<String, Object> mynotfound = result.get("my/notfound/class");
assertEquals(2, mynotfound.size());
assertEquals("", mynotfound.get("test()V"));
assertEquals("", mynotfound.get("test2()V"));
ConcurrentHashMap<String, Object> socketInputStream = result.get("java/net/SocketInputStream");
assertEquals(2, socketInputStream.size());
assertEquals("", socketInputStream.get("read([B)I"));
assertEquals("", socketInputStream.get("read([BII)I"));
assertEquals(1, upperMarks.size());
TreeMap<String, String> sessionInputBuffer = upperMarks.get("org/apache/http/io/SessionInputBuffer");
assertEquals(2, sessionInputBuffer.size());
assertEquals("#mark from sub org/apache/http/impl/io/AbstractSessionInputBuffer", sessionInputBuffer.get("read([BII)I"));
assertEquals("#mark from sub org/apache/http/impl/io/AbstractSessionInputBuffer", sessionInputBuffer.get("readLine(Lorg/apache/http/util/CharArrayBuffer;)I"));
}
}