diff options
author | Adam Domurad <[email protected]> | 2013-04-25 17:05:31 -0400 |
---|---|---|
committer | Adam Domurad <[email protected]> | 2013-04-25 17:05:31 -0400 |
commit | 6d5754626525233d2bda2e388632f8b4476484c9 (patch) | |
tree | 51f9d21ddf410be3415509ddfd2a7a6f0941b9de /tests/test-extensions | |
parent | 61ca0a975341f40fbbb46379b10fbf77f0bf3d95 (diff) |
Add accidentally not included files
Diffstat (limited to 'tests/test-extensions')
-rw-r--r-- | tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java | 102 | ||||
-rw-r--r-- | tests/test-extensions/sun/applet/mock/PluginPipeMock.java | 121 |
2 files changed, 223 insertions, 0 deletions
diff --git a/tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java b/tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java new file mode 100644 index 0000000..f3f1716 --- /dev/null +++ b/tests/test-extensions/net/sourceforge/jnlp/AsyncCall.java @@ -0,0 +1,102 @@ +package net.sourceforge.jnlp; + +import java.util.concurrent.Callable; + +/** + * A call that runs on a separate thread, with an optional timeout. It takes a runnable and allows + * joining. + * + * On join, throws any exceptions that occurred within the call, or a TimeOutException if + * it did not finish. Returns the value from the call. + */ +public class AsyncCall<T> { + static public class TimeOutException extends RuntimeException { + public TimeOutException() { + super("Call did not finish within the allocated time."); + } + } + + private Thread handler; + private Callable<T> callable; + private long timeout; + private T callResult; + + /* Captures exception from async call */ + private Exception asyncException = null; + + /* Create an AsyncCall with a given time-out */ + public AsyncCall(Callable<T> callable, long timeout) { + this.callable = callable; + this.timeout = timeout; + this.handler = new HandlerThread(); + } + + /* Create an AsyncCall with (effectively) no time-out */ + public AsyncCall(Callable<T> call) { + this(call, Long.MAX_VALUE); + } + + /* Chains construction + start for convenience */ + public static <T> AsyncCall<T> startWithTimeOut(Callable<T> callable, long timeout) { + AsyncCall<T> asyncCall = new AsyncCall<T>(callable, timeout); + asyncCall.start(); + return asyncCall; + } + + /* Chains construction + start for convenience */ + public static <T> AsyncCall<T> startWithTimeOut(Callable<T> callable) { + return startWithTimeOut(callable, 1000); // Default timeout of 1 second + } + + public void start() { + this.handler.start(); + } + + // Rethrows exceptions from handler thread, and throws TimeOutException in case of time-out. + public T join() throws Exception { + handler.join(); + if (asyncException != null) { + throw asyncException; + } + return callResult; + } + + /* The handler thread is responsible for timing-out the Callable thread. + * The resulting thread */ + private class HandlerThread extends Thread { + @Override + public void run() { + Thread thread = new Thread() { + @Override + public void run() { + try { + /* Capture result of the call */ + callResult = callable.call(); + } catch (Exception e) { + /* In case of exception, capture for re-throw */ + asyncException = e; + } + handler.interrupt(); // Finish early + } + }; + + thread.start(); + + try { + Thread.sleep(timeout); + } catch (InterruptedException e) { + // Finish early + return; + } + + if (thread.isAlive()) { + asyncException = new TimeOutException(); + } + + // Make sure the thread is finished + while (thread.isAlive()) { + thread.interrupt(); + } + } + } +} diff --git a/tests/test-extensions/sun/applet/mock/PluginPipeMock.java b/tests/test-extensions/sun/applet/mock/PluginPipeMock.java new file mode 100644 index 0000000..2435c66 --- /dev/null +++ b/tests/test-extensions/sun/applet/mock/PluginPipeMock.java @@ -0,0 +1,121 @@ +package sun.applet.mock; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringReader; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * Helper for getting an input & output stream for use with PluginStreamHandler. + * Provides a convenient way of reading the Java requests and sending mocked + * plugin responses. + * + * The handling of these requests should be done on a different thread from the + * tested method, as icedtea-web will block waiting for a reply after sending a + * request. + */ +public class PluginPipeMock { + private ResponseInputPipeMock responseInputStream = new ResponseInputPipeMock(); + private RequestOutputPipeMock requestOutputStream = new RequestOutputPipeMock(); + + /* + * A queue of mocked responses that are sent as replies to icedtea-web + * Java-side requests. + */ + private BlockingQueue<String> mockedResponseQueue = new LinkedBlockingQueue<String>(); + + /* + * A queue of actual (ie, not mocked) requests that come from methods + * under test. + */ + private BlockingQueue<String> requestQueue = new LinkedBlockingQueue<String>(); + + public InputStream getResponseInputStream() { + return responseInputStream; + } + + public OutputStream getRequestOutputStream() { + return requestOutputStream; + } + + public String getNextRequest() { + try { + return requestQueue.take(); + } catch (InterruptedException e) { + // Nothing to do + return null; + } + } + + public void sendResponse(String response) { + try { + mockedResponseQueue.put(response); + } catch (InterruptedException e) { + // Nothing to do + } + } + + /** + * Queues mocked responses and sends them as replies to icedtea-web. A + * synchronized message queue is read from. Blocks until it gets the next + * message. + */ + private class ResponseInputPipeMock extends InputStream { + private StringReader reader = null; + + @Override + public int read() throws IOException { + try { + while (true) { + if (reader == null) { + reader = new StringReader(mockedResponseQueue.take() + '\n'); + } + int chr = reader.read(); + if (chr == -1) { + reader = null; + continue; + } + return chr; + } + } catch (InterruptedException e) { + // Nothing to do + return -1; + } + } + + /* Necessary for correct behaviour with BufferedReader! */ + @Override + public int read(byte b[], int off, int len) throws IOException { + if (len == 0) { + return 0; + } + b[off] = (byte) read(); + return 1; + } + } + + /** + * Outputs requests from icedtea-web as a stream of lines. A synchronized + * message queue is written to. + */ + private class RequestOutputPipeMock extends OutputStream { + private StringBuilder lineBuffer = new StringBuilder(); + + @Override + public synchronized void write(int b) throws IOException { + try { + char chr = (char) b; + if (chr == '\0') { + requestQueue.put(lineBuffer.toString()); + lineBuffer.setLength(0); + } else { + lineBuffer.append((char) b); + } + } catch (InterruptedException e) { + // Nothing to do + } + } + } +} |