package net.sourceforge.stripes.mock;
import net.sourceforge.stripes.FilterEnabledTestBase;
import net.sourceforge.stripes.action.*;
import static org.testng.Assert.*;
import net.sourceforge.stripes.controller.AsyncEvent;
import net.sourceforge.stripes.controller.AsyncListener;
import net.sourceforge.stripes.controller.AsyncResponse;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestMockAsync extends FilterEnabledTestBase {
private AsyncActionBean execute(String eventName) throws Exception {
System.out.println("==> Executing : " + eventName);
MockRoundtrip trip = new MockRoundtrip(getMockServletContext(), AsyncActionBean.class);
trip.execute(eventName);
AsyncActionBean bean = trip.getActionBean(AsyncActionBean.class);
assertNotNull(bean);
assertEquals(eventName, bean.getContext().getEventName());
assertTrue(bean.completed);
assertTrue(trip.getRequest().getAsyncContext().isCompleted());
System.out.println("==> done with : " + eventName);
return bean;
}
@Test
public void testSuccess() throws Exception {
AsyncActionBean bean = execute("doAsync");
assertNotNull(bean);
assertTrue(bean.isCompleted());
}
@Test
public void testReallyAsync() throws Exception {
AsyncActionBean bean = execute("doReallyAsync");
assertNotNull(bean);
assertTrue(bean.isCompleted());
}
@Test
public void testTimeout() throws Exception {
MockRoundtrip trip = new MockRoundtrip(getMockServletContext(), AsyncActionBean.class);
boolean caught = false;
try {
trip.execute("doAsyncTimeout");
} catch(Exception e) {
caught = true;
e.printStackTrace();
}
assertTrue(caught);
AsyncActionBean bean = trip.getActionBean(AsyncActionBean.class);
assertNotNull(bean);
assertTrue(!bean.isCompleted());
HttpServletResponse response = bean.getContext().getResponse();
assertEquals(response.getStatus(), 500);
assertTrue(trip.getRequest().getAsyncContext().isCompleted());
}
@Test
public void testRegularException() throws Exception {
boolean caught = false;
try {
MockRoundtrip trip = new MockRoundtrip(getMockServletContext(), AsyncActionBean.class);
trip.execute("doRegularException");
} catch(Exception e) {
e.printStackTrace();
caught = true;
}
assertTrue(caught);
}
private void assertThrows(String event) {
boolean caught = false;
try {
MockRoundtrip trip = new MockRoundtrip(getMockServletContext(), AsyncActionBean.class);
trip.execute(event);
assertTrue(trip.getRequest().getAsyncContext().isCompleted());
} catch(Exception e) {
e.printStackTrace();
caught = true;
}
assertTrue(caught);
}
@Test
public void testAsyncException() throws Exception {
assertThrows("doAsyncException");
}
@Test
public void testCompleteWithForwardResolution() throws Exception {
execute("doAsyncAndCompleteWithForwardResolution");
}
@Test
public void doAsyncInThreadAndCompleteWithForwardResolution() throws Exception {
execute("doAsyncInThreadAndCompleteWithForwardResolution");
}
@Test
public void doAsyncInThreadWithListener() throws Exception {
execute("doAsyncInThreadWithListener");
}
@Test
public void doAsyncWithResolutionThatThrows() throws Exception {
assertThrows("doAsyncWithResolutionThatThrows");
}
@Test
public void doAsyncWithForwardToNowhere() throws Exception {
MockRoundtrip trip = new MockRoundtrip(getMockServletContext(), AsyncActionBean.class);
trip.execute("doAsyncWithForwardToNowhere");
AsyncActionBean bean = trip.getActionBean(AsyncActionBean.class);
assertNotNull(bean);
assertEquals("doAsyncWithForwardToNowhere", bean.getContext().getEventName());
assertFalse(bean.completed);
assertTrue(trip.getRequest().getAsyncContext().isCompleted());
}
@UrlBinding("/async")
public static class AsyncActionBean implements ActionBean {
private boolean completed = false;
private ActionBeanContext context;
public ActionBeanContext getContext() {
return context;
}
public void setContext(ActionBeanContext context) {
this.context = context;
}
@DefaultHandler
public void doAsync(AsyncResponse r) throws Exception {
System.out.println("Not Really Async...");
r.getResponse().getWriter().write("DONE");
completed = true;
r.complete();
}
public void doReallyAsync(final AsyncResponse r) throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Really Async !");
try {
r.getResponse().getWriter().write("DONE");
completed = true;
r.complete();
} catch (IOException e) {
e.printStackTrace(); // we let it timeout...
}
}
}).start();
}
public void doAsyncTimeout(AsyncResponse r) {
r.setTimeout(1000);
// we never complete !
}
public Resolution doRegularException() {
throw new RuntimeException("boom");
}
public void doAsyncException(AsyncResponse r) {
throw new RuntimeException("Async boom");
}
public void doAsyncAndCompleteWithForwardResolution(AsyncResponse r) {
System.out.println("hiya, I'm forwarding...");
completed = true;
r.complete(new ForwardResolution("/foo/bar.jsp"));
}
public void doAsyncInThreadAndCompleteWithForwardResolution(final AsyncResponse response) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hiya, I'm inside a separate thread");
completed = true;
System.out.println("Completing");
response.complete(new ForwardResolution("/foo/bar.jsp"));
}
}).start();
}
public void doAsyncInThreadWithListener(final AsyncResponse response) {
// set the completed flag with a listener
response.addListener(new AsyncListener() {
@Override
public void onComplete(AsyncEvent event) {
completed = true;
}
@Override
public void onError(AsyncEvent event) {
}
@Override
public void onTimeout(AsyncEvent event) {
}
});
new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0 ; i < 10 ; i++) {
response.getResponse().getWriter().write("i=" + i);
Thread.sleep(100);
}
System.out.println("hiya, I'm inside a separate thread and I use listeners");
} catch (Exception e) {
e.printStackTrace();
}
response.complete();
}
}).start();
}
public void doAsyncWithResolutionThatThrows(final AsyncResponse asyncResponse) {
asyncResponse.complete(new ResolutionThatThrows());
}
public void doAsyncWithForwardToNowhere(final AsyncResponse asyncResponse) {
asyncResponse.complete(new ForwardResolution("/i/dont/exist"));
}
public boolean isCompleted() {
return completed;
}
}
private static class ResolutionThatThrows implements Resolution {
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
throw new RuntimeException("I throw exceptions only");
}
}
}