diff options
author | Elliott Hughes <enh@google.com> | 2012-09-25 15:29:36 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2012-09-25 15:36:03 -0700 |
commit | 3d43199950729e592ac3e104442b4b350a86aec8 (patch) | |
tree | 6c2ce26e1549c40d6d775ca0866b4dd452b1c7b1 | |
parent | 6d41a7cc3cb4cc684c8bece69ddc55954812ad6e (diff) | |
download | libcore-3d43199950729e592ac3e104442b4b350a86aec8.zip libcore-3d43199950729e592ac3e104442b4b350a86aec8.tar.gz libcore-3d43199950729e592ac3e104442b4b350a86aec8.tar.bz2 |
Fix ConcurrentCloseTest flakiness.
We were running the risk that the server's end of a client socket would get
closed by the finalizer thread, resulting in read(2) returning 0 to the client,
and the test failing like this:
junit.framework.AssertionFailedError: read returned -1
at libcore.java.net.ConcurrentCloseTest.test_read(ConcurrentCloseTest.java:121)
at java.lang.reflect.Method.invokeNative(Native Method)
(cherry-pick of 4bbcd7e5aee1e984a4fcf46385667f9ad03dbc16.)
Bug: 7206024
Change-Id: I0dae214a7ee609655f4f4781abf4457863bcfd5f
-rw-r--r-- | luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java b/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java index d33c5f3..06a546a 100644 --- a/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java +++ b/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java @@ -16,11 +16,13 @@ package libcore.java.net; +import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketAddress; import java.net.SocketException; import java.nio.channels.AsynchronousCloseException; import java.nio.channels.ClosedChannelException; @@ -102,16 +104,7 @@ public class ConcurrentCloseTest extends junit.framework.TestCase { } public void test_read() throws Exception { - final ServerSocket ss = new ServerSocket(0); - new Thread(new Runnable() { - public void run() { - try { - ss.accept(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - }).start(); + SilentServer ss = new SilentServer(); Socket s = new Socket(); s.connect(ss.getLocalSocketAddress()); new Killer(s).start(); @@ -126,16 +119,7 @@ public class ConcurrentCloseTest extends junit.framework.TestCase { } public void test_read_multiple() throws Throwable { - final ServerSocket ss = new ServerSocket(0); - new Thread(new Runnable() { - public void run() { - try { - ss.accept(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - }).start(); + SilentServer ss = new SilentServer(); final Socket s = new Socket(); s.connect(ss.getLocalSocketAddress()); @@ -173,6 +157,8 @@ public class ConcurrentCloseTest extends junit.framework.TestCase { for (Throwable exception : thrownExceptions) { throw exception; } + + ss.close(); } public void test_recv() throws Exception { @@ -190,21 +176,7 @@ public class ConcurrentCloseTest extends junit.framework.TestCase { } public void test_write() throws Exception { - final ServerSocket ss = new ServerSocket(0); - new Thread(new Runnable() { - public void run() { - try { - System.err.println("accepting..."); - - Socket client = ss.accept(); - System.err.println("accepted..."); - Thread.sleep(30 * 1000); - System.err.println("server exiting..."); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - }).start(); + final SilentServer ss = new SilentServer(); Socket s = new Socket(); s.connect(ss.getLocalSocketAddress()); new Killer(s).start(); @@ -224,6 +196,37 @@ public class ConcurrentCloseTest extends junit.framework.TestCase { ss.close(); } + // This server accepts connections, but doesn't read or write anything. + // It holds on to the Socket connecting to the client so it won't be GCed. + // Call "close" to close both the server socket and its client connection. + static class SilentServer { + private final ServerSocket ss; + private Socket client; + + public SilentServer() throws IOException { + ss = new ServerSocket(0); + new Thread(new Runnable() { + public void run() { + try { + client = ss.accept(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + }).start(); + } + + public SocketAddress getLocalSocketAddress() { + return ss.getLocalSocketAddress(); + } + + public void close() throws IOException { + client.close(); + ss.close(); + } + } + + // This thread calls the "close" method on the supplied T after 2s. static class Killer<T> extends Thread { private final T s; |