package fr.gael.dhus.util.http; import java.io.IOException; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.InterruptibleChannel; import java.nio.channels.WritableByteChannel; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.entity.StringEntity; import org.apache.http.impl.bootstrap.HttpServer; import org.apache.http.impl.bootstrap.ServerBootstrap; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.testng.Assert; import org.testng.annotations.Test; /** Tests for InterruptibleHttpClient */ public class TestInterruptibleHttpClient { /** Is getInterruptible able to get? */ @Test public void testGet () throws IOException, InterruptedException { InterruptibleHttpClient ihc = new InterruptibleHttpClient (); DummyChannel output = new DummyChannel (); String url = "http://localhost:" + String.valueOf (DummyHttpServer.start ()) + '/'; HttpResponse response = ihc.interruptibleGet (url, output); DummyHttpServer.stop (); // The requested site must have a `Content-Length` header field and must not have a chunk-encoded body long contentlength = response.getEntity ().getContentLength (); Assert.assertEquals (contentlength, output.getRead ()); } /** Is getInterruptible really interruptible? */ @Test (timeOut = 2000L) public void testGetInterrupted () throws IOException, InterruptedException { final InterruptibleHttpClient ihc = new InterruptibleHttpClient (); ServerSocket ss = new ServerSocket (0); final String url = "http://localhost:" + String.valueOf (ss.getLocalPort ()) + '/'; Thread t = new Thread (new Runnable () { @Override public void run () { try { ihc.interruptibleGet (url, new DummyChannel ()); } catch (IOException | InterruptedException ex) { } } }); t.start (); Thread.sleep (1000L); t.interrupt (); ss.close (); t.join (); } /** A dummy channel for testing purposes. */ private static class DummyChannel implements InterruptibleChannel, WritableByteChannel { /** A counter that counts how many bytes have been written. */ private long counter = 0L; /** Open/Close status of this channel. */ private boolean status = true; /** * Returns how many bytes have been written. * * @return value of write counter. */ long getRead () { return counter; } @Override public void close () throws IOException { status = false; } @Override public boolean isOpen () { return status; } @Override public int write (ByteBuffer src) throws IOException { if (!status) { throw new IOException (); } counter += src.remaining (); return src.remaining (); } } /** A dummy HTTP server for testing purposes. */ private static class DummyHttpServer { private static HttpServer server = null; /** * Starts the HTTP server. * * @return the listening port. */ static int start () throws IOException { server = ServerBootstrap.bootstrap ().registerHandler ("*", new HttpRequestHandler () { @Override public void handle (HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { response.setStatusCode (HttpStatus.SC_OK); response.setEntity (new StringEntity ("0123456789")); } }) .create (); server.start (); return server.getLocalPort (); } /** * Stops the HTTP server. */ static void stop () { server.stop (); server = null; } } }