# HG changeset patch # User chegar # Date 1396262020 -3600 # Node ID 5c29c65ae465ca958c75a56c7ff9a64989dbfb3d # Parent c561991073ad9abdaaab1508e3ac878255066062 8025209: Intermittent test failure java/net/Socket/asyncClose/AsyncClose.java Reviewed-by: chegar Contributed-by: Eric Wang , Chris Hegarty diff -r c561991073ad -r 5c29c65ae465 jdk/test/java/net/Socket/asyncClose/AsyncClose.java --- a/jdk/test/java/net/Socket/asyncClose/AsyncClose.java Mon Mar 31 11:28:03 2014 +0200 +++ b/jdk/test/java/net/Socket/asyncClose/AsyncClose.java Mon Mar 31 11:33:40 2014 +0100 @@ -21,15 +21,17 @@ * questions. */ +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import static java.util.concurrent.CompletableFuture.*; + /* * @test * @bug 4344135 * @summary Check that {Socket,ServerSocket,DatagramSocket}.close will * cause any thread blocked on the socket to throw a SocketException. - * @run main/timeout=60 AsyncClose */ -import java.net.*; -import java.io.*; public class AsyncClose { @@ -37,34 +39,35 @@ AsyncCloseTest tests[] = { new Socket_getInputStream_read(), - new Socket_getInputStream_read(5000), + new Socket_getInputStream_read(20000), new Socket_getOutputStream_write(), new DatagramSocket_receive(), - new DatagramSocket_receive(5000), + new DatagramSocket_receive(20000), new ServerSocket_accept(), - new ServerSocket_accept(5000), + new ServerSocket_accept(20000), }; int failures = 0; - for (int i=0; i> cfs = new ArrayList<>(); + for (AsyncCloseTest test : tests) + cfs.add( supplyAsync(() -> test.go())); + + for (CompletableFuture cf : cfs) { + AsyncCloseTest test = cf.get(); System.out.println("******************************"); - System.out.println("Test: " + tst.description()); - - if (tst.go()) { + System.out.println("Test: " + test.description()); + if (test.hasPassed()) { System.out.println("Passed."); } else { - System.out.println("Failed: " + tst.failureReason()); + System.out.println("Failed: " + test.failureReason()); failures++; } System.out.println(""); - } - if (failures > 0) { + if (failures > 0) throw new Exception(failures + " sub-tests failed - see log."); - } } } diff -r c561991073ad -r 5c29c65ae465 jdk/test/java/net/Socket/asyncClose/AsyncCloseTest.java --- a/jdk/test/java/net/Socket/asyncClose/AsyncCloseTest.java Mon Mar 31 11:28:03 2014 +0200 +++ b/jdk/test/java/net/Socket/asyncClose/AsyncCloseTest.java Mon Mar 31 11:33:40 2014 +0100 @@ -29,11 +29,22 @@ public abstract String description(); - public abstract boolean go() throws Exception; + public abstract AsyncCloseTest go(); + public synchronized boolean hasPassed() { + return passed; + } - protected synchronized void failed(String reason) { - this.reason = reason; + protected synchronized AsyncCloseTest passed() { + if (reason == null) + passed = true; + return this; + } + + protected synchronized AsyncCloseTest failed(String r) { + passed = false; + reason = r; + return this; } public synchronized String failureReason() { @@ -48,7 +59,7 @@ return closed; } + private boolean passed; private String reason; private boolean closed; - } diff -r c561991073ad -r 5c29c65ae465 jdk/test/java/net/Socket/asyncClose/DatagramSocket_receive.java --- a/jdk/test/java/net/Socket/asyncClose/DatagramSocket_receive.java Mon Mar 31 11:28:03 2014 +0200 +++ b/jdk/test/java/net/Socket/asyncClose/DatagramSocket_receive.java Mon Mar 31 11:33:40 2014 +0100 @@ -26,20 +26,25 @@ * throws a SocketException if the socket is asynchronously closed. */ import java.net.*; +import java.util.concurrent.CountDownLatch; public class DatagramSocket_receive extends AsyncCloseTest implements Runnable { - DatagramSocket s; - int timeout = 0; + private final DatagramSocket s; + private final int timeout; + private final CountDownLatch latch; - public DatagramSocket_receive() { + public DatagramSocket_receive() throws SocketException { + this(0); } - public DatagramSocket_receive(int timeout) { + public DatagramSocket_receive(int timeout) throws SocketException { this.timeout = timeout; + latch = new CountDownLatch(1); + s = new DatagramSocket(); } public String description() { - String s = "DatagramSocket.receive"; + String s = "DatagramSocket.receive(DatagramPacket)"; if (timeout > 0) { s += " (timeout specified)"; } @@ -47,46 +52,45 @@ } public void run() { - DatagramPacket p; try { - byte b[] = new byte[1024]; - p = new DatagramPacket(b, b.length); - + DatagramPacket p = new DatagramPacket(b, b.length); if (timeout > 0) { s.setSoTimeout(timeout); } + latch.countDown(); + s.receive(p); + failed("DatagramSocket.receive(DatagramPacket) returned unexpectly!!"); + } catch (SocketException se) { + if (latch.getCount() != 1) { + closed(); + } } catch (Exception e) { failed(e.getMessage()); - return; - } - - try { - s.receive(p); - } catch (SocketException se) { - closed(); - } catch (Exception e) { - failed(e.getMessage()); + } finally { + if (latch.getCount() == 1) { + latch.countDown(); + } } } - public boolean go() throws Exception { - s = new DatagramSocket(); - - Thread thr = new Thread(this); - thr.start(); - - Thread.currentThread().sleep(1000); + public AsyncCloseTest go() { + try { + Thread thr = new Thread(this); + thr.start(); + latch.await(); + Thread.sleep(5000); //sleep, so receive(DatagramPacket) can block + s.close(); + thr.join(); - s.close(); - - Thread.currentThread().sleep(1000); - - if (isClosed()) { - return true; - } else { - failed("DatagramSocket.receive wasn't preempted"); - return false; + if (isClosed()) { + return passed(); + } else { + return failed("DatagramSocket.receive(DatagramPacket) wasn't preempted"); + } + } catch (Exception x) { + failed(x.getMessage()); + throw new RuntimeException(x); } } } diff -r c561991073ad -r 5c29c65ae465 jdk/test/java/net/Socket/asyncClose/ServerSocket_accept.java --- a/jdk/test/java/net/Socket/asyncClose/ServerSocket_accept.java Mon Mar 31 11:28:03 2014 +0200 +++ b/jdk/test/java/net/Socket/asyncClose/ServerSocket_accept.java Mon Mar 31 11:33:40 2014 +0100 @@ -25,17 +25,23 @@ * Tests that a thread blocked in ServerSocket.accept * throws a SocketException if the socket is asynchronously closed. */ +import java.io.IOException; import java.net.*; +import java.util.concurrent.CountDownLatch; public class ServerSocket_accept extends AsyncCloseTest implements Runnable { - ServerSocket ss; - int timeout = 0; + private final ServerSocket ss; + private final int timeout; + private final CountDownLatch latch; - public ServerSocket_accept() { + public ServerSocket_accept() throws IOException { + this(0); } - public ServerSocket_accept(int timeout) { + public ServerSocket_accept(int timeout) throws IOException { this.timeout = timeout; + latch = new CountDownLatch(1); + ss = new ServerSocket(0); } public String description() { @@ -48,7 +54,9 @@ public void run() { try { + latch.countDown(); Socket s = ss.accept(); + failed("ServerSocket.accept() returned unexpectly!!"); } catch (SocketException se) { closed(); } catch (Exception e) { @@ -56,23 +64,23 @@ } } - public boolean go() throws Exception { - ss = new ServerSocket(0); - - Thread thr = new Thread(this); - thr.start(); - - Thread.currentThread().sleep(1000); + public AsyncCloseTest go(){ + try { + Thread thr = new Thread(this); + thr.start(); + latch.await(); + Thread.sleep(5000); //sleep, so ServerSocket.accept() can block + ss.close(); + thr.join(); - ss.close(); - - Thread.currentThread().sleep(1000); - - if (isClosed()) { - return true; - } else { - failed("ServerSocket.accept() wasn't preempted"); - return false; + if (isClosed()) { + return passed(); + } else { + return failed("ServerSocket.accept() wasn't preempted"); + } + } catch (Exception x) { + failed(x.getMessage()); + throw new RuntimeException(x); } } } diff -r c561991073ad -r 5c29c65ae465 jdk/test/java/net/Socket/asyncClose/Socket_getInputStream_read.java --- a/jdk/test/java/net/Socket/asyncClose/Socket_getInputStream_read.java Mon Mar 31 11:28:03 2014 +0200 +++ b/jdk/test/java/net/Socket/asyncClose/Socket_getInputStream_read.java Mon Mar 31 11:33:40 2014 +0100 @@ -27,16 +27,21 @@ */ import java.net.*; import java.io.*; +import java.util.concurrent.CountDownLatch; public class Socket_getInputStream_read extends AsyncCloseTest implements Runnable { - Socket s; - int timeout = 0; + private final Socket s; + private final int timeout; + private final CountDownLatch latch; public Socket_getInputStream_read() { + this(0); } public Socket_getInputStream_read(int timeout) { this.timeout = timeout; + latch = new CountDownLatch(1); + s = new Socket(); } public String description() { @@ -48,53 +53,48 @@ } public void run() { - InputStream in; - try { - in = s.getInputStream(); + InputStream in = s.getInputStream(); if (timeout > 0) { s.setSoTimeout(timeout); } + latch.countDown(); + int n = in.read(); + failed("Socket.getInputStream().read() returned unexpectly!!"); + } catch (SocketException se) { + if (latch.getCount() != 1) { + closed(); + } } catch (Exception e) { failed(e.getMessage()); - return; - } - - try { - int n = in.read(); - failed("getInptuStream().read() returned unexpectly!!"); - } catch (SocketException se) { - closed(); - } catch (Exception e) { - failed(e.getMessage()); + } finally { + if (latch.getCount() == 1) { + latch.countDown(); + } } } - public boolean go() throws Exception { - - ServerSocket ss = new ServerSocket(0); - - InetAddress lh = InetAddress.getLocalHost(); - s = new Socket(); - s.connect( new InetSocketAddress(lh, ss.getLocalPort()) ); - - Socket s2 = ss.accept(); - - Thread thr = new Thread(this); - thr.start(); + public AsyncCloseTest go() { + try { + ServerSocket ss = new ServerSocket(0); + InetAddress lh = InetAddress.getLocalHost(); + s.connect( new InetSocketAddress(lh, ss.getLocalPort()) ); + Socket s2 = ss.accept(); + Thread thr = new Thread(this); + thr.start(); + latch.await(); + Thread.sleep(5000); //sleep, so Socket.getInputStream().read() can block + s.close(); + thr.join(); - Thread.currentThread().sleep(1000); - - s.close(); - - Thread.currentThread().sleep(1000); - - if (isClosed()) { - return true; - } else { - failed("getInputStream().read() wasn't preempted"); - return false; + if (isClosed()) { + return passed(); + } else { + return failed("Socket.getInputStream().read() wasn't preempted"); + } + } catch (Exception x) { + failed(x.getMessage()); + throw new RuntimeException(x); } - } } diff -r c561991073ad -r 5c29c65ae465 jdk/test/java/net/Socket/asyncClose/Socket_getOutputStream_write.java --- a/jdk/test/java/net/Socket/asyncClose/Socket_getOutputStream_write.java Mon Mar 31 11:28:03 2014 +0200 +++ b/jdk/test/java/net/Socket/asyncClose/Socket_getOutputStream_write.java Mon Mar 31 11:33:40 2014 +0100 @@ -27,9 +27,16 @@ */ import java.net.*; import java.io.*; +import java.util.concurrent.CountDownLatch; public class Socket_getOutputStream_write extends AsyncCloseTest implements Runnable { - Socket s; + private final Socket s; + private final CountDownLatch latch; + + public Socket_getOutputStream_write() { + latch = new CountDownLatch(1); + s = new Socket(); + } public String description() { return "Socket.getOutputStream().write()"; @@ -38,40 +45,45 @@ public void run() { try { OutputStream out = s.getOutputStream(); + byte b[] = new byte[8192]; + latch.countDown(); for (;;) { - byte b[] = new byte[8192]; out.write(b); } } catch (SocketException se) { - closed(); + if (latch.getCount() != 1) { + closed(); + } } catch (Exception e) { failed(e.getMessage()); + } finally { + if (latch.getCount() == 1) { + latch.countDown(); + } } } - public boolean go() throws Exception { - ServerSocket ss = new ServerSocket(0); - - InetAddress lh = InetAddress.getLocalHost(); - s = new Socket(); - s.connect( new InetSocketAddress(lh, ss.getLocalPort()) ); - - Socket s2 = ss.accept(); - - Thread thr = new Thread(this); - thr.start(); + public AsyncCloseTest go() { + try { + ServerSocket ss = new ServerSocket(0); + InetAddress lh = InetAddress.getLocalHost(); + s.connect( new InetSocketAddress(lh, ss.getLocalPort()) ); + Socket s2 = ss.accept(); + Thread thr = new Thread(this); + thr.start(); + latch.await(); + Thread.sleep(1000); + s.close(); + thr.join(); - Thread.currentThread().sleep(2000); - - s.close(); - - Thread.currentThread().sleep(2000); - - if (isClosed()) { - return true; - } else { - failed("getOutputStream().write() wasn't preempted"); - return false; + if (isClosed()) { + return passed(); + } else { + return failed("Socket.getOutputStream().write() wasn't preempted"); + } + } catch (Exception x) { + failed(x.getMessage()); + throw new RuntimeException(x); } } }