diff options
-rw-r--r-- | expectations/knownfailures.txt | 6 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/net/URLConnectionTest.java | 46 | ||||
-rw-r--r-- | support/src/test/java/tests/http/MockWebServer.java | 94 |
3 files changed, 98 insertions, 48 deletions
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt index 54510bf..9b60457 100644 --- a/expectations/knownfailures.txt +++ b/expectations/knownfailures.txt @@ -12,6 +12,12 @@ bug: 3325799 }, { + description: "URLConnection fails on URLs containing {}", + name: "libcore.java.net.URLConnectionTest#testMalformedUrl", + bug: 1158780, + substring: "java.net.URISyntaxException" +}, +{ description: "Test regression", name: "libcore.javax.crypto.spec.KeyFactoryTestDSA#testKeyFactory", substring: "not implemented yet", diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java index 6fe8515..2e6a25d 100644 --- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java +++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java @@ -25,6 +25,7 @@ import java.io.OutputStream; import java.net.Authenticator; import java.net.CacheRequest; import java.net.CacheResponse; +import java.net.ConnectException; import java.net.HttpRetryException; import java.net.HttpURLConnection; import java.net.InetAddress; @@ -1542,10 +1543,10 @@ public class URLConnectionTest extends junit.framework.TestCase { assertEquals(Arrays.asList("verify " + hostname), hostnameVerifier.calls); assertEquals(Arrays.asList("checkServerTrusted [" - + "CN=" + hostname + " 1, " - + "CN=Test Intermediate Certificate Authority 1, " - + "CN=Test Root Certificate Authority 1" - + "] RSA"), + + "CN=" + hostname + " 1, " + + "CN=Test Intermediate Certificate Authority 1, " + + "CN=Test Root Certificate Authority 1" + + "] RSA"), trustManager.calls); } finally { HttpsURLConnection.setDefaultHostnameVerifier(defaultHostnameVerifier); @@ -1557,11 +1558,15 @@ public class URLConnectionTest extends junit.framework.TestCase { StuckServer ss = new StuckServer(); int serverPort = ss.getLocalPort(); URLConnection urlConnection = new URL("http://localhost:" + serverPort).openConnection(); - urlConnection.setConnectTimeout(1000); + int timeout = 1000; + urlConnection.setConnectTimeout(timeout); + long start = System.currentTimeMillis(); try { urlConnection.getInputStream(); fail(); } catch (SocketTimeoutException expected) { + long actual = System.currentTimeMillis() - start; + assertTrue(Math.abs(timeout - actual) < 500); } finally { ss.close(); } @@ -1578,6 +1583,7 @@ public class URLConnectionTest extends junit.framework.TestCase { .clearHeaders() .addHeader("Content-Length: 4"); server.enqueue(timeout); + server.enqueue(new MockResponse().setBody("unused")); // to keep the server alive server.play(); URLConnection urlConnection = server.getUrl("/").openConnection(); @@ -1741,6 +1747,36 @@ public class URLConnectionTest extends junit.framework.TestCase { } } + public void testGetKeepAlive() throws Exception { + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setBody("ABC")); + server.play(); + + // The request should work once and then fail + URLConnection connection = server.getUrl("").openConnection(); + InputStream input = connection.getInputStream(); + assertEquals("ABC", readAscii(input, Integer.MAX_VALUE)); + input.close(); + try { + server.getUrl("").openConnection().getInputStream(); + fail(); + } catch (ConnectException expected) { + } + } + + /** + * Test that we support URLs containing '{' and '}'. http://b/1158780 + */ + public void testMalformedUrl() throws Exception { + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setResponseCode(404)); + server.play(); + + URL url = server.getUrl("/search?q={foo}+{bar}"); + HttpURLConnection connection = (HttpURLConnection)url.openConnection(); + assertEquals(404, connection.getResponseCode()); + } + /** * Encodes the response body using GZIP and adds the corresponding header. */ diff --git a/support/src/test/java/tests/http/MockWebServer.java b/support/src/test/java/tests/http/MockWebServer.java index c0ce671..4a2b7ec 100644 --- a/support/src/test/java/tests/http/MockWebServer.java +++ b/support/src/test/java/tests/http/MockWebServer.java @@ -28,6 +28,7 @@ import java.net.MalformedURLException; import java.net.Proxy; import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketException; import java.net.URL; import java.net.UnknownHostException; import java.util.ArrayList; @@ -37,12 +38,13 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import static tests.http.SocketPolicy.DISCONNECT_AT_START; @@ -55,6 +57,7 @@ public final class MockWebServer { static final String ASCII = "US-ASCII"; + private static final Logger logger = Logger.getLogger(MockWebServer.class.getName()); private final BlockingQueue<RecordedRequest> requestQueue = new LinkedBlockingQueue<RecordedRequest>(); private final BlockingQueue<MockResponse> responseQueue @@ -157,13 +160,12 @@ public final class MockWebServer { serverSocket.setReuseAddress(true); port = serverSocket.getLocalPort(); - executor.submit(namedCallable("MockWebServer-accept-" + port, new Callable<Void>() { - public Void call() throws Exception { - List<Throwable> failures = new ArrayList<Throwable>(); + executor.execute(namedRunnable("MockWebServer-accept-" + port, new Runnable() { + public void run() { try { acceptConnections(); } catch (Throwable e) { - failures.add(e); + logger.log(Level.WARNING, "MockWebServer connection failed", e); } /* @@ -173,49 +175,39 @@ public final class MockWebServer { try { serverSocket.close(); } catch (Throwable e) { - failures.add(e); + logger.log(Level.WARNING, "MockWebServer server socket close failed", e); } - for (Iterator<Socket> s = openClientSockets.iterator(); s.hasNext(); ) { + for (Iterator<Socket> s = openClientSockets.iterator(); s.hasNext();) { try { s.next().close(); s.remove(); } catch (Throwable e) { - failures.add(e); + logger.log(Level.WARNING, "MockWebServer socket close failed", e); } } try { executor.shutdown(); } catch (Throwable e) { - failures.add(e); - } - if (!failures.isEmpty()) { - Throwable thrown = failures.get(0); - if (thrown instanceof Exception) { - throw (Exception) thrown; - } else { - throw (Error) thrown; - } - } else { - return null; + logger.log(Level.WARNING, "MockWebServer executor shutdown failed", e); } } - public void acceptConnections() throws Exception { - int count = 0; - while (true) { - if (count > 0 && responseQueue.isEmpty()) { - return; + private void acceptConnections() throws Exception { + while (!responseQueue.isEmpty()) { + Socket socket; + try { + socket = serverSocket.accept(); + } catch (SocketException ignored) { + continue; } - - Socket socket = serverSocket.accept(); - if (responseQueue.peek().getSocketPolicy() == DISCONNECT_AT_START) { + MockResponse peek = responseQueue.peek(); + if (peek != null && peek.getSocketPolicy() == DISCONNECT_AT_START) { responseQueue.take(); socket.close(); - continue; + } else { + openClientSockets.add(socket); + serveConnection(socket); } - openClientSockets.add(socket); - serveConnection(socket); - count++; } } })); @@ -229,10 +221,18 @@ public final class MockWebServer { private void serveConnection(final Socket raw) { String name = "MockWebServer-" + raw.getRemoteSocketAddress(); - executor.submit(namedCallable(name, new Callable<Void>() { + executor.execute(namedRunnable(name, new Runnable() { int sequenceNumber = 0; - public Void call() throws Exception { + public void run() { + try { + processConnection(); + } catch (Exception e) { + logger.log(Level.WARNING, "MockWebServer connection failed", e); + } + } + + public void processConnection() throws Exception { Socket socket; if (sslSocketFactory != null) { if (tunnelProxy) { @@ -252,16 +252,19 @@ public final class MockWebServer { InputStream in = new BufferedInputStream(socket.getInputStream()); OutputStream out = new BufferedOutputStream(socket.getOutputStream()); - if (!processOneRequest(in, out, socket)) { - throw new IllegalStateException("Connection without any request!"); + while (!responseQueue.isEmpty() && processOneRequest(in, out, socket)) {} + + if (sequenceNumber == 0) { + logger.warning("MockWebServer connection didn't make a request"); } - while (processOneRequest(in, out, socket)) {} in.close(); out.close(); socket.close(); + if (responseQueue.isEmpty()) { + shutdown(); + } openClientSockets.remove(socket); - return null; } /** @@ -294,9 +297,14 @@ public final class MockWebServer { * @param sequenceNumber the index of this request on this connection. */ private RecordedRequest readRequest(InputStream in, int sequenceNumber) throws IOException { - String request = readAsciiUntilCrlf(in); + String request; + try { + request = readAsciiUntilCrlf(in); + } catch (IOException streamIsClosed) { + return null; // no request because we closed the stream + } if (request.isEmpty()) { - return null; // end of data; no more requests + return null; // no request because the stream is exhausted } List<String> headers = new ArrayList<String>(); @@ -437,13 +445,13 @@ public final class MockWebServer { } } - private static <T> Callable<T> namedCallable(final String name, final Callable<T> callable) { - return new Callable<T>() { - public T call() throws Exception { + private static Runnable namedRunnable(final String name, final Runnable runnable) { + return new Runnable() { + public void run() { String originalName = Thread.currentThread().getName(); Thread.currentThread().setName(name); try { - return callable.call(); + runnable.run(); } finally { Thread.currentThread().setName(originalName); } |