package nginx.clojure;
import static org.junit.Assert.assertTrue;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import clojure.lang.AFn;
import clojure.lang.IFn;
import clojure.lang.PersistentArrayMap;
import clojure.lang.RT;
import clojure.lang.Symbol;
import clojure.lang.Var;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class CompojureHandlerTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testSimpleHandler1() {
RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.compojure-fns-for-test"));
// System.out.println("rq cl :" + rq.getClass().getClassLoader());
final IFn fn = (IFn)RT.var("nginx.clojure.compojure-fns-for-test", "simple-handler").fn();
for (int i = 0; i < 2; i++) {
final Map<String,Object> resp = new HashMap<String, Object>();
System.out.println("test at i=" + i);
Coroutine cr = new Coroutine(new Runnable() {
@Override
public void run() throws SuspendExecution {
resp.putAll((Map)fn.invoke());
}
});
cr.resume();
Assert.assertEquals(0, resp.size());
System.out.println("before resume");
cr.resume();
Assert.assertEquals(3, resp.size());
Assert.assertEquals("Simple Response\n", resp.get(RT.keyword(null, "body")));
Assert.assertEquals(Coroutine.State.FINISHED, cr.getState());
assertTrue(cr.getStack().allObjsAreNull());
// Stack st = Stack.getStack();
// System.out.println(st.curMethodSP);
}
}
@Test
public void testSimpleHandler11() {
System.out.println("do test testSimpleHandler11");
RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.compojure-fns-for-test"));
// System.out.println("rq cl :" + rq.getClass().getClassLoader());
final IFn fn = (IFn)RT.var("nginx.clojure.compojure-fns-for-test", "simple-handler").fn();
final Map<String,Object> resp = new HashMap<String, Object>();
Coroutine cr = new Coroutine(new Runnable() {
@Override
public void run() throws SuspendExecution {
resp.putAll((Map)fn.invoke());
}
});
cr.resume();
Assert.assertEquals(0, resp.size());
System.out.println("before resume");
cr.resume();
Assert.assertEquals(3, resp.size());
Assert.assertEquals("Simple Response\n", resp.get(RT.keyword(null, "body")));
assertTrue(cr.getStack().allObjsAreNull());
}
public static final class MyRunner implements Runnable {
Object request;
Map response = new HashMap();
final IFn handler;
public MyRunner(IFn handler, Object request) {
super();
if (handler instanceof Var) {
handler = ((Var)handler).fn();
}
this.handler = handler;
this.request = request;
}
@SuppressWarnings("rawtypes")
@Override
public void run() throws SuspendExecution {
try {
response = (Map) handler.invoke(request);
}catch(Throwable e) {
System.err.println("in coroutine run handler error");
e.printStackTrace();
}
}
}
@Test
public void testSimpleHandler2() {
RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.compojure-fns-for-test"));
// System.out.println("rq cl :" + rq.getClass().getClassLoader());
IFn fn = (IFn)RT.var("nginx.clojure.compojure-fns-for-test", "simple-selfresume-handler").fn();
MyRunner myrunner = new MyRunner(fn, "just a test");
Coroutine cr = new Coroutine(myrunner);
cr.resume();
Assert.assertEquals(0, myrunner.response.size());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Assert.assertEquals(3, myrunner.response.size());
Assert.assertEquals("Simple Response\n", myrunner.response.get(RT.keyword(null, "body")));
assertTrue(cr.getStack().allObjsAreNull());
}
@Test
public void testSimpleHandler3() {
RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.coroutine-socket-handlers-for-test"));
// System.out.println("rq cl :" + rq.getClass().getClassLoader());
// IFn fn = (IFn)RT.var("nginx.clojure.coroutine-socket-handlers-for-test", "coroutine-socket-test-handler").fn();
String code = "(do " +
"(use \'[compojure.core])" +
"(use \'[nginx.clojure.coroutine-socket-handlers-for-test])" +
"(context \"/coroutineSocketAndCompojure\" [] coroutine-socket-test-handler)" +
// "coroutine-socket-test-handler" +
")";
IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(code));
//{:uri "/simple", :scheme :http, :request-method :get, :headers {}}
PersistentArrayMap request = new PersistentArrayMap(new Object[] {
RT.keyword(null, "uri"), "/coroutineSocketAndCompojure/simple"
// RT.keyword(null, "uri"), "/simple"
,RT.keyword(null, "scheme"), RT.keyword(null, "http")
,RT.keyword(null, "request-method"), RT.keyword(null, "get")
,RT.keyword(null, "headers"), PersistentArrayMap.EMPTY
});
MyRunner myrunner = new MyRunner(fn, request);
Coroutine cr = new Coroutine(myrunner);
cr.resume();
Assert.assertEquals(0, myrunner.response.size());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Assert.assertEquals(3, myrunner.response.size());
Assert.assertEquals("Simple Response\n", myrunner.response.get(RT.keyword(null, "body")));
assertTrue(cr.getStack().allObjsAreNull());
}
@Test
public void testSimpleHandler30() {
final MyRunner[] ref = new MyRunner[1];
RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.coroutine-socket-handlers-for-test"));
// System.out.println("rq cl :" + rq.getClass().getClassLoader());
// IFn fn = (IFn)RT.var("nginx.clojure.coroutine-socket-handlers-for-test", "coroutine-socket-test-handler").fn();
String code = "(do " +
"(use \'[compojure.core])" +
"(use \'[nginx.clojure.coroutine-socket-handlers-for-test])" +
"(context \"/coroutineSocketAndCompojure\" [] coroutine-socket-test-handler)" +
// "coroutine-socket-test-handler" +
")";
// final IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(code));
final IFn fn = new AFn() {
@Override
public Object invoke(Object req) {
final Coroutine co = Coroutine.getActiveCoroutine();
Thread selfresume = new Thread() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
co.resume();
};
};
selfresume.start();
Coroutine.yield();
PersistentArrayMap resp = new PersistentArrayMap(new Object[]{
RT.keyword(null, "status"), "200",
RT.keyword(null, "headers"), "",
RT.keyword(null, "body"), "Simple Response\n"
});
return resp;
}
};
Runnable runnable = new Runnable() {
@Override
public void run() throws SuspendExecution {
//{:uri "/simple", :scheme :http, :request-method :get, :headers {}}
PersistentArrayMap request = new PersistentArrayMap(new Object[] {
RT.keyword(null, "uri"), "/coroutineSocketAndCompojure/simple"
// RT.keyword(null, "uri"), "/simple"
,RT.keyword(null, "scheme"), RT.keyword(null, "http")
,RT.keyword(null, "request-method"), RT.keyword(null, "get")
,RT.keyword(null, "headers"), PersistentArrayMap.EMPTY
});
MyRunner myRunner = ref[0] = new MyRunner(fn, request);
myRunner.run();
System.out.println("end of run");
}
};
Coroutine cr = new Coroutine(runnable);
cr.resume();
MyRunner myrunner = ref[0];
Assert.assertEquals(0, myrunner.response.size());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Assert.assertEquals(3, myrunner.response.size());
Assert.assertEquals("Simple Response\n", myrunner.response.get(RT.keyword(null, "body")));
assertTrue(cr.getStack().allObjsAreNull());
}
@Test
public void testSimpleHandler31() {
RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.coroutine-socket-handlers-for-test"));
// System.out.println("rq cl :" + rq.getClass().getClassLoader());
// IFn fn = (IFn)RT.var("nginx.clojure.coroutine-socket-handlers-for-test", "coroutine-socket-test-handler").fn();
String code = "(do " +
"(use \'[compojure.core])" +
"(use \'[nginx.clojure.coroutine-socket-handlers-for-test])" +
// "(context \"/coroutineSocketAndCompojure\" [] coroutine-socket-test-handler)" +
"coroutine-socket-test-handler" +
")";
IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(code));
//{:uri "/simple", :scheme :http, :request-method :get, :headers {}}
PersistentArrayMap request = new PersistentArrayMap(new Object[] {
// RT.keyword(null, "uri"), "/coroutineSocketAndCompojure/simple"
RT.keyword(null, "uri"), "/simple"
,RT.keyword(null, "scheme"), RT.keyword(null, "http")
,RT.keyword(null, "request-method"), RT.keyword(null, "get")
,RT.keyword(null, "headers"), PersistentArrayMap.EMPTY
});
MyRunner myrunner = new MyRunner(fn, request);
Coroutine cr = new Coroutine(myrunner);
cr.resume();
Assert.assertEquals(0, myrunner.response.size());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Assert.assertEquals(3, myrunner.response.size());
Assert.assertEquals("Simple Response\n", myrunner.response.get(RT.keyword(null, "body")));
assertTrue(cr.getStack().allObjsAreNull());
}
@Test
public void testSimpleHandler32() {
RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.coroutine-socket-handlers-for-test"));
// System.out.println("rq cl :" + rq.getClass().getClassLoader());
IFn fn = (IFn)RT.var("nginx.clojure.coroutine-socket-handlers-for-test", "simple-handler").fn();
// String code = "(do " +
// "(use \'[compojure.core])" +
// "(use \'[nginx.clojure.coroutine-socket-handlers-for-test])" +
//// "(context \"/coroutineSocketAndCompojure\" [] coroutine-socket-test-handler)" +
// "coroutine-socket-test-handler" +
// ")";
// IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(code));
//{:uri "/simple", :scheme :http, :request-method :get, :headers {}}
PersistentArrayMap request = new PersistentArrayMap(new Object[] {
// RT.keyword(null, "uri"), "/coroutineSocketAndCompojure/simple"
RT.keyword(null, "uri"), "/simple2"
,RT.keyword(null, "scheme"), RT.keyword(null, "http")
,RT.keyword(null, "request-method"), RT.keyword(null, "get")
,RT.keyword(null, "headers"), PersistentArrayMap.EMPTY
});
MyRunner myrunner = new MyRunner(fn, request);
Coroutine cr = new Coroutine(myrunner);
cr.resume();
Assert.assertEquals(0, myrunner.response.size());
cr.resume();
Assert.assertEquals(3, myrunner.response.size());
Assert.assertEquals("Simple Response\n", myrunner.response.get(RT.keyword(null, "body")));
assertTrue(cr.getStack().allObjsAreNull());
}
@Test
public void testSimpleHandler4() {
IFn fn = new AFn() {
@Override
public Object invoke(Object arg1) throws SuspendExecution {
System.out.println("before");
final Coroutine cr = Coroutine.getActiveCoroutine();
new Thread() {
public void run() {
try {
Thread.sleep(2000);
cr.resume();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
Coroutine.yield();
System.out.println("after");
return new PersistentArrayMap(new Object[]{
RT.keyword(null, "body"), "Simple Response\n",
RT.keyword(null, "headers"), PersistentArrayMap.EMPTY,
RT.keyword(null, "status"), "200",
});
}
};
//{:uri "/simple", :scheme :http, :request-method :get, :headers {}}
PersistentArrayMap request = new PersistentArrayMap(new Object[] {
// RT.keyword(null, "uri"), "/coroutineSocketAndCompojure/simple"
RT.keyword(null, "uri"), "/simple"
,RT.keyword(null, "scheme"), RT.keyword(null, "http")
,RT.keyword(null, "request-method"), RT.keyword(null, "get")
,RT.keyword(null, "headers"), PersistentArrayMap.EMPTY
});
MyRunner myrunner = new MyRunner(fn, request);
Coroutine cr = new Coroutine(myrunner);
cr.resume();
Assert.assertEquals(0, myrunner.response.size());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Assert.assertEquals(3, myrunner.response.size());
Assert.assertEquals("Simple Response\n", myrunner.response.get(RT.keyword(null, "body")));
assertTrue(cr.getStack().allObjsAreNull());
}
}