提交 87c8c1a6 编写于 作者: C chegar

8025209: Intermittent test failure java/net/Socket/asyncClose/AsyncClose.java

Reviewed-by: chegar
Contributed-by: NEric Wang &lt;yiming.wang@oracle.com&gt;, Chris Hegarty <chris.hegarty@oracle.com>
上级 43745cf8
...@@ -21,15 +21,17 @@ ...@@ -21,15 +21,17 @@
* questions. * questions.
*/ */
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static java.util.concurrent.CompletableFuture.*;
/* /*
* @test * @test
* @bug 4344135 * @bug 4344135
* @summary Check that {Socket,ServerSocket,DatagramSocket}.close will * @summary Check that {Socket,ServerSocket,DatagramSocket}.close will
* cause any thread blocked on the socket to throw a SocketException. * 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 { public class AsyncClose {
...@@ -37,34 +39,35 @@ public class AsyncClose { ...@@ -37,34 +39,35 @@ public class AsyncClose {
AsyncCloseTest tests[] = { AsyncCloseTest tests[] = {
new Socket_getInputStream_read(), new Socket_getInputStream_read(),
new Socket_getInputStream_read(5000), new Socket_getInputStream_read(20000),
new Socket_getOutputStream_write(), new Socket_getOutputStream_write(),
new DatagramSocket_receive(), new DatagramSocket_receive(),
new DatagramSocket_receive(5000), new DatagramSocket_receive(20000),
new ServerSocket_accept(), new ServerSocket_accept(),
new ServerSocket_accept(5000), new ServerSocket_accept(20000),
}; };
int failures = 0; int failures = 0;
for (int i=0; i<tests.length; i++) { List<CompletableFuture<AsyncCloseTest>> cfs = new ArrayList<>();
AsyncCloseTest tst = tests[i]; for (AsyncCloseTest test : tests)
cfs.add( supplyAsync(() -> test.go()));
System.out.println("******************************"); for (CompletableFuture<AsyncCloseTest> cf : cfs) {
System.out.println("Test: " + tst.description()); AsyncCloseTest test = cf.get();
if (tst.go()) { System.out.println("******************************");
System.out.println("Test: " + test.description());
if (test.hasPassed()) {
System.out.println("Passed."); System.out.println("Passed.");
} else { } else {
System.out.println("Failed: " + tst.failureReason()); System.out.println("Failed: " + test.failureReason());
failures++; failures++;
} }
System.out.println(""); System.out.println("");
} }
if (failures > 0) { if (failures > 0)
throw new Exception(failures + " sub-tests failed - see log."); throw new Exception(failures + " sub-tests failed - see log.");
}
} }
} }
...@@ -29,11 +29,22 @@ public abstract class AsyncCloseTest { ...@@ -29,11 +29,22 @@ public abstract class AsyncCloseTest {
public abstract String description(); public abstract String description();
public abstract boolean go() throws Exception; public abstract AsyncCloseTest go();
public synchronized boolean hasPassed() {
return passed;
}
protected synchronized AsyncCloseTest passed() {
if (reason == null)
passed = true;
return this;
}
protected synchronized void failed(String reason) { protected synchronized AsyncCloseTest failed(String r) {
this.reason = reason; passed = false;
reason = r;
return this;
} }
public synchronized String failureReason() { public synchronized String failureReason() {
...@@ -48,7 +59,7 @@ public abstract class AsyncCloseTest { ...@@ -48,7 +59,7 @@ public abstract class AsyncCloseTest {
return closed; return closed;
} }
private boolean passed;
private String reason; private String reason;
private boolean closed; private boolean closed;
} }
...@@ -26,20 +26,25 @@ ...@@ -26,20 +26,25 @@
* throws a SocketException if the socket is asynchronously closed. * throws a SocketException if the socket is asynchronously closed.
*/ */
import java.net.*; import java.net.*;
import java.util.concurrent.CountDownLatch;
public class DatagramSocket_receive extends AsyncCloseTest implements Runnable { public class DatagramSocket_receive extends AsyncCloseTest implements Runnable {
DatagramSocket s; private final DatagramSocket s;
int timeout = 0; 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; this.timeout = timeout;
latch = new CountDownLatch(1);
s = new DatagramSocket();
} }
public String description() { public String description() {
String s = "DatagramSocket.receive"; String s = "DatagramSocket.receive(DatagramPacket)";
if (timeout > 0) { if (timeout > 0) {
s += " (timeout specified)"; s += " (timeout specified)";
} }
...@@ -47,46 +52,45 @@ public class DatagramSocket_receive extends AsyncCloseTest implements Runnable { ...@@ -47,46 +52,45 @@ public class DatagramSocket_receive extends AsyncCloseTest implements Runnable {
} }
public void run() { public void run() {
DatagramPacket p;
try { try {
byte b[] = new byte[1024]; byte b[] = new byte[1024];
p = new DatagramPacket(b, b.length); DatagramPacket p = new DatagramPacket(b, b.length);
if (timeout > 0) { if (timeout > 0) {
s.setSoTimeout(timeout); s.setSoTimeout(timeout);
} }
} catch (Exception e) { latch.countDown();
failed(e.getMessage());
return;
}
try {
s.receive(p); s.receive(p);
failed("DatagramSocket.receive(DatagramPacket) returned unexpectly!!");
} catch (SocketException se) { } catch (SocketException se) {
closed(); if (latch.getCount() != 1) {
closed();
}
} catch (Exception e) { } catch (Exception e) {
failed(e.getMessage()); failed(e.getMessage());
} finally {
if (latch.getCount() == 1) {
latch.countDown();
}
} }
} }
public boolean go() throws Exception { public AsyncCloseTest go() {
s = new DatagramSocket(); try {
Thread thr = new Thread(this);
Thread thr = new Thread(this); thr.start();
thr.start(); latch.await();
Thread.sleep(5000); //sleep, so receive(DatagramPacket) can block
Thread.currentThread().sleep(1000); s.close();
thr.join();
s.close();
Thread.currentThread().sleep(1000);
if (isClosed()) { if (isClosed()) {
return true; return passed();
} else { } else {
failed("DatagramSocket.receive wasn't preempted"); return failed("DatagramSocket.receive(DatagramPacket) wasn't preempted");
return false; }
} catch (Exception x) {
failed(x.getMessage());
throw new RuntimeException(x);
} }
} }
} }
...@@ -25,17 +25,23 @@ ...@@ -25,17 +25,23 @@
* Tests that a thread blocked in ServerSocket.accept * Tests that a thread blocked in ServerSocket.accept
* throws a SocketException if the socket is asynchronously closed. * throws a SocketException if the socket is asynchronously closed.
*/ */
import java.io.IOException;
import java.net.*; import java.net.*;
import java.util.concurrent.CountDownLatch;
public class ServerSocket_accept extends AsyncCloseTest implements Runnable { public class ServerSocket_accept extends AsyncCloseTest implements Runnable {
ServerSocket ss; private final ServerSocket ss;
int timeout = 0; 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; this.timeout = timeout;
latch = new CountDownLatch(1);
ss = new ServerSocket(0);
} }
public String description() { public String description() {
...@@ -48,7 +54,9 @@ public class ServerSocket_accept extends AsyncCloseTest implements Runnable { ...@@ -48,7 +54,9 @@ public class ServerSocket_accept extends AsyncCloseTest implements Runnable {
public void run() { public void run() {
try { try {
latch.countDown();
Socket s = ss.accept(); Socket s = ss.accept();
failed("ServerSocket.accept() returned unexpectly!!");
} catch (SocketException se) { } catch (SocketException se) {
closed(); closed();
} catch (Exception e) { } catch (Exception e) {
...@@ -56,23 +64,23 @@ public class ServerSocket_accept extends AsyncCloseTest implements Runnable { ...@@ -56,23 +64,23 @@ public class ServerSocket_accept extends AsyncCloseTest implements Runnable {
} }
} }
public boolean go() throws Exception { public AsyncCloseTest go(){
ss = new ServerSocket(0); try {
Thread thr = new Thread(this);
Thread thr = new Thread(this); thr.start();
thr.start(); latch.await();
Thread.sleep(5000); //sleep, so ServerSocket.accept() can block
Thread.currentThread().sleep(1000); ss.close();
thr.join();
ss.close();
Thread.currentThread().sleep(1000);
if (isClosed()) { if (isClosed()) {
return true; return passed();
} else { } else {
failed("ServerSocket.accept() wasn't preempted"); return failed("ServerSocket.accept() wasn't preempted");
return false; }
} catch (Exception x) {
failed(x.getMessage());
throw new RuntimeException(x);
} }
} }
} }
...@@ -27,16 +27,21 @@ ...@@ -27,16 +27,21 @@
*/ */
import java.net.*; import java.net.*;
import java.io.*; import java.io.*;
import java.util.concurrent.CountDownLatch;
public class Socket_getInputStream_read extends AsyncCloseTest implements Runnable { public class Socket_getInputStream_read extends AsyncCloseTest implements Runnable {
Socket s; private final Socket s;
int timeout = 0; private final int timeout;
private final CountDownLatch latch;
public Socket_getInputStream_read() { public Socket_getInputStream_read() {
this(0);
} }
public Socket_getInputStream_read(int timeout) { public Socket_getInputStream_read(int timeout) {
this.timeout = timeout; this.timeout = timeout;
latch = new CountDownLatch(1);
s = new Socket();
} }
public String description() { public String description() {
...@@ -48,53 +53,48 @@ public class Socket_getInputStream_read extends AsyncCloseTest implements Runnab ...@@ -48,53 +53,48 @@ public class Socket_getInputStream_read extends AsyncCloseTest implements Runnab
} }
public void run() { public void run() {
InputStream in;
try { try {
in = s.getInputStream(); InputStream in = s.getInputStream();
if (timeout > 0) { if (timeout > 0) {
s.setSoTimeout(timeout); s.setSoTimeout(timeout);
} }
} catch (Exception e) { latch.countDown();
failed(e.getMessage());
return;
}
try {
int n = in.read(); int n = in.read();
failed("getInptuStream().read() returned unexpectly!!"); failed("Socket.getInputStream().read() returned unexpectly!!");
} catch (SocketException se) { } catch (SocketException se) {
closed(); if (latch.getCount() != 1) {
closed();
}
} catch (Exception e) { } catch (Exception e) {
failed(e.getMessage()); failed(e.getMessage());
} finally {
if (latch.getCount() == 1) {
latch.countDown();
}
} }
} }
public boolean go() throws Exception { public AsyncCloseTest go() {
try {
ServerSocket ss = new ServerSocket(0); ServerSocket ss = new ServerSocket(0);
InetAddress lh = InetAddress.getLocalHost();
InetAddress lh = InetAddress.getLocalHost(); s.connect( new InetSocketAddress(lh, ss.getLocalPort()) );
s = new Socket(); Socket s2 = ss.accept();
s.connect( new InetSocketAddress(lh, ss.getLocalPort()) ); Thread thr = new Thread(this);
thr.start();
Socket s2 = ss.accept(); latch.await();
Thread.sleep(5000); //sleep, so Socket.getInputStream().read() can block
Thread thr = new Thread(this); s.close();
thr.start(); thr.join();
Thread.currentThread().sleep(1000); if (isClosed()) {
return passed();
s.close(); } else {
return failed("Socket.getInputStream().read() wasn't preempted");
Thread.currentThread().sleep(1000); }
} catch (Exception x) {
if (isClosed()) { failed(x.getMessage());
return true; throw new RuntimeException(x);
} else {
failed("getInputStream().read() wasn't preempted");
return false;
} }
} }
} }
...@@ -27,9 +27,16 @@ ...@@ -27,9 +27,16 @@
*/ */
import java.net.*; import java.net.*;
import java.io.*; import java.io.*;
import java.util.concurrent.CountDownLatch;
public class Socket_getOutputStream_write extends AsyncCloseTest implements Runnable { 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() { public String description() {
return "Socket.getOutputStream().write()"; return "Socket.getOutputStream().write()";
...@@ -38,40 +45,45 @@ public class Socket_getOutputStream_write extends AsyncCloseTest implements Runn ...@@ -38,40 +45,45 @@ public class Socket_getOutputStream_write extends AsyncCloseTest implements Runn
public void run() { public void run() {
try { try {
OutputStream out = s.getOutputStream(); OutputStream out = s.getOutputStream();
byte b[] = new byte[8192];
latch.countDown();
for (;;) { for (;;) {
byte b[] = new byte[8192];
out.write(b); out.write(b);
} }
} catch (SocketException se) { } catch (SocketException se) {
closed(); if (latch.getCount() != 1) {
closed();
}
} catch (Exception e) { } catch (Exception e) {
failed(e.getMessage()); failed(e.getMessage());
} finally {
if (latch.getCount() == 1) {
latch.countDown();
}
} }
} }
public boolean go() throws Exception { public AsyncCloseTest go() {
ServerSocket ss = new ServerSocket(0); try {
ServerSocket ss = new ServerSocket(0);
InetAddress lh = InetAddress.getLocalHost(); InetAddress lh = InetAddress.getLocalHost();
s = new Socket(); s.connect( new InetSocketAddress(lh, ss.getLocalPort()) );
s.connect( new InetSocketAddress(lh, ss.getLocalPort()) ); Socket s2 = ss.accept();
Thread thr = new Thread(this);
Socket s2 = ss.accept(); thr.start();
latch.await();
Thread thr = new Thread(this); Thread.sleep(1000);
thr.start(); s.close();
thr.join();
Thread.currentThread().sleep(2000);
s.close();
Thread.currentThread().sleep(2000);
if (isClosed()) { if (isClosed()) {
return true; return passed();
} else { } else {
failed("getOutputStream().write() wasn't preempted"); return failed("Socket.getOutputStream().write() wasn't preempted");
return false; }
} catch (Exception x) {
failed(x.getMessage());
throw new RuntimeException(x);
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册