Skip to content

Commit 8e98ce5

Browse files
committed
8231506: Fix some instabilities in a few networking tests
Reviewed-by: alanb, chegar, msheppar
1 parent 990ec34 commit 8e98ce5

File tree

3 files changed

+107
-25
lines changed

3 files changed

+107
-25
lines changed

test/jdk/java/net/MulticastSocket/UnreferencedMulticastSockets.java

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import java.util.ArrayDeque;
5151
import java.util.List;
5252
import java.util.Optional;
53+
import java.util.concurrent.Phaser;
5354
import java.util.concurrent.TimeUnit;
5455

5556
import jdk.test.lib.net.IPSupport;
@@ -72,11 +73,14 @@ public class UnreferencedMulticastSockets {
7273
static class Server implements Runnable {
7374

7475
MulticastSocket ss;
75-
76+
final int port;
77+
final Phaser phaser = new Phaser(2);
7678
Server() throws IOException {
79+
InetAddress loopback = InetAddress.getLoopbackAddress();
7780
InetSocketAddress serverAddress =
78-
new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
81+
new InetSocketAddress(loopback, 0);
7982
ss = new MulticastSocket(serverAddress);
83+
port = ss.getLocalPort();
8084
System.out.printf(" DatagramServer addr: %s: %d%n",
8185
this.getHost(), this.getPort());
8286
pendingSockets.add(new NamedWeak(ss, pendingQueue, "serverMulticastSocket"));
@@ -89,7 +93,7 @@ InetAddress getHost() throws UnknownHostException {
8993
}
9094

9195
int getPort() {
92-
return ss.getLocalPort();
96+
return port;
9397
}
9498

9599
// Receive a byte and send back a byte
@@ -98,12 +102,18 @@ public void run() {
98102
byte[] buffer = new byte[50];
99103
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
100104
ss.receive(p);
105+
System.out.printf("Server: ping received from: %s%n", p.getSocketAddress());
106+
phaser.arriveAndAwaitAdvance(); // await the client...
101107
buffer[0] += 1;
108+
System.out.printf("Server: sending echo to: %s%n", p.getSocketAddress());
102109
ss.send(p); // send back +1
103110

111+
System.out.printf("Server: awaiting client%n");
112+
phaser.arriveAndAwaitAdvance(); // await the client...
104113
// do NOT close but 'forget' the socket reference
114+
System.out.printf("Server: forgetting socket...%n");
105115
ss = null;
106-
} catch (Exception ioe) {
116+
} catch (Throwable ioe) {
107117
ioe.printStackTrace();
108118
}
109119
}
@@ -112,8 +122,11 @@ public void run() {
112122
public static void main(String args[]) throws Exception {
113123
IPSupport.throwSkippedExceptionIfNonOperational();
114124

125+
InetSocketAddress clientAddress =
126+
new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
127+
115128
// Create and close a MulticastSocket to warm up the FD count for side effects.
116-
try (MulticastSocket s = new MulticastSocket(0)) {
129+
try (MulticastSocket s = new MulticastSocket(clientAddress)) {
117130
// no-op; close immediately
118131
s.getLocalPort(); // no-op
119132
}
@@ -126,8 +139,33 @@ public static void main(String args[]) throws Exception {
126139
Thread thr = new Thread(svr);
127140
thr.start();
128141

129-
MulticastSocket client = new MulticastSocket(0);
130-
System.out.printf(" client bound port: %d%n", client.getLocalPort());
142+
// It is possible under some circumstances that the client
143+
// might get bound to the same port than the server: this
144+
// would make the test fail - so if this happen we try to
145+
// bind to a specific port by incrementing the server port.
146+
MulticastSocket client = null;
147+
int serverPort = svr.getPort();
148+
int maxtries = 20;
149+
for (int i = 0; i < maxtries; i++) {
150+
try {
151+
System.out.printf("Trying to bind client to: %s%n", clientAddress);
152+
client = new MulticastSocket(clientAddress);
153+
if (client.getLocalPort() != svr.getPort()) break;
154+
client.close();
155+
} catch (IOException x) {
156+
System.out.printf("Couldn't create client after %d attempts: %s%n", i, x);
157+
if (i == maxtries) throw x;
158+
}
159+
if (i == maxtries) {
160+
String msg = String.format("Couldn't create client after %d attempts", i);
161+
System.out.println(msg);
162+
throw new AssertionError(msg);
163+
}
164+
clientAddress = new InetSocketAddress(clientAddress.getAddress(), serverPort + i);
165+
}
166+
167+
System.out.printf(" client bound port: %s:%d%n",
168+
client.getLocalAddress(), client.getLocalPort());
131169
client.connect(svr.getHost(), svr.getPort());
132170
pendingSockets.add(new NamedWeak(client, pendingQueue, "clientMulticastSocket"));
133171
extractRefs(client, "clientMulticastSocket");
@@ -136,14 +174,17 @@ public static void main(String args[]) throws Exception {
136174
msg[0] = 1;
137175
DatagramPacket p = new DatagramPacket(msg, msg.length, svr.getHost(), svr.getPort());
138176
client.send(p);
177+
System.out.printf(" ping sent to: %s:%d%n", svr.getHost(), svr.getPort());
178+
svr.phaser.arriveAndAwaitAdvance(); // wait until the server has received its packet
139179

140180
p = new DatagramPacket(msg, msg.length);
141181
client.receive(p);
142182

143-
System.out.printf("echo received from: %s%n", p.getSocketAddress());
183+
System.out.printf(" echo received from: %s%n", p.getSocketAddress());
144184
if (msg[0] != 2) {
145185
throw new AssertionError("incorrect data received: expected: 2, actual: " + msg[0]);
146186
}
187+
svr.phaser.arriveAndAwaitAdvance(); // let the server null out its socket
147188

148189
// Do NOT close the MulticastSocket; forget it
149190

test/jdk/java/net/SocketImpl/SocketImplCombinations.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void testNewSocket1() throws IOException {
6868
* Test creating a connected Socket, it should be created with a platform SocketImpl.
6969
*/
7070
public void testNewSocket2() throws IOException {
71-
try (ServerSocket ss = new ServerSocket(0)) {
71+
try (ServerSocket ss = boundServerSocket()) {
7272
try (Socket s = new Socket(ss.getInetAddress(), ss.getLocalPort())) {
7373
SocketImpl si = getSocketImpl(s);
7474
assertTrue(isSocksSocketImpl(si));
@@ -127,7 +127,7 @@ public void testNewSocket6() throws IOException {
127127
Socket s = new Socket((SocketImpl) null) { };
128128
try (s) {
129129
assertTrue(getSocketImpl(s) == null);
130-
s.bind(new InetSocketAddress(0)); // force SocketImpl to be created
130+
s.bind(loopbackSocketAddress()); // force SocketImpl to be created
131131
SocketImpl si = getSocketImpl(s);
132132
assertTrue(isSocksSocketImpl(si));
133133
SocketImpl delegate = getDelegate(si);
@@ -218,7 +218,7 @@ public void testNewSocket12() throws IOException {
218218
Socket s = new Socket((SocketImpl) null) { };
219219
try (s) {
220220
assertTrue(getSocketImpl(s) == null);
221-
s.bind(new InetSocketAddress(0)); // force SocketImpl to be created
221+
s.bind(loopbackSocketAddress()); // force SocketImpl to be created
222222
assertTrue(getSocketImpl(s) instanceof CustomSocketImpl);
223223
}
224224
} finally {
@@ -378,7 +378,7 @@ public void testServerSocketAccept4b() throws IOException {
378378
public void testServerSocketAccept5a() throws IOException {
379379
SocketImpl serverImpl = new CustomSocketImpl(true);
380380
try (ServerSocket ss = new ServerSocket(serverImpl) { }) {
381-
ss.bind(new InetSocketAddress(0));
381+
ss.bind(loopbackSocketAddress());
382382
expectThrows(IOException.class, ss::accept);
383383
}
384384
}
@@ -565,17 +565,37 @@ static void serverSocketAccept(SocketImpl impl,
565565
}
566566
}
567567

568+
/**
569+
* Returns a new InetSocketAddress with the loopback interface
570+
* and port 0.
571+
*/
572+
static InetSocketAddress loopbackSocketAddress() {
573+
InetAddress loopback = InetAddress.getLoopbackAddress();
574+
return new InetSocketAddress(loopback, 0);
575+
}
576+
577+
/**
578+
* Returns a ServerSocket bound to a port on the loopback address
579+
*/
580+
static ServerSocket boundServerSocket() throws IOException {
581+
ServerSocket ss = new ServerSocket();
582+
ss.bind(loopbackSocketAddress());
583+
return ss;
584+
}
585+
568586
/**
569587
* Creates a ServerSocket that returns the given Socket from accept.
570588
*/
571589
static ServerSocket serverSocketToAccept(Socket s) throws IOException {
572-
return new ServerSocket(0) {
590+
ServerSocket ss = new ServerSocket() {
573591
@Override
574592
public Socket accept() throws IOException {
575593
implAccept(s);
576594
return s;
577595
}
578596
};
597+
ss.bind(loopbackSocketAddress());
598+
return ss;
579599
}
580600

581601
/**
@@ -590,7 +610,7 @@ public Socket accept() throws IOException {
590610
return s;
591611
}
592612
};
593-
ss.bind(new InetSocketAddress(0));
613+
ss.bind(loopbackSocketAddress());
594614
return ss;
595615
}
596616

test/jdk/java/net/httpclient/DigestEchoServer.java

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import com.sun.net.httpserver.HttpsConfigurator;
2727
import com.sun.net.httpserver.HttpsParameters;
2828
import com.sun.net.httpserver.HttpsServer;
29+
30+
import java.io.Closeable;
2931
import java.io.IOException;
3032
import java.io.InputStream;
3133
import java.io.OutputStream;
@@ -1568,8 +1570,8 @@ private synchronized Thread pipe(InputStream is, OutputStream os, char tag, Comp
15681570
@Override
15691571
public void run() {
15701572
try {
1573+
int c = 0;
15711574
try {
1572-
int c;
15731575
while ((c = is.read()) != -1) {
15741576
os.write(c);
15751577
os.flush();
@@ -1578,11 +1580,13 @@ public void run() {
15781580
if (DEBUG) System.out.print(tag);
15791581
}
15801582
is.close();
1583+
} catch (IOException ex) {
1584+
if (DEBUG || !stopped && c > -1)
1585+
ex.printStackTrace(System.out);
1586+
end.completeExceptionally(ex);
15811587
} finally {
1582-
os.close();
1588+
try {os.close();} catch (Throwable t) {}
15831589
}
1584-
} catch (IOException ex) {
1585-
if (DEBUG) ex.printStackTrace(System.out);
15861590
} finally {
15871591
end.complete(null);
15881592
}
@@ -1632,10 +1636,12 @@ String readLine(InputStream r) throws IOException {
16321636
@Override
16331637
public void run() {
16341638
Socket clientConnection = null;
1639+
Socket targetConnection = null;
16351640
try {
16361641
while (!stopped) {
16371642
System.out.println(now() + "Tunnel: Waiting for client");
16381643
Socket toClose;
1644+
targetConnection = clientConnection = null;
16391645
try {
16401646
toClose = clientConnection = ss.accept();
16411647
if (NO_LINGER) {
@@ -1649,7 +1655,6 @@ public void run() {
16491655
}
16501656
System.out.println(now() + "Tunnel: Client accepted");
16511657
StringBuilder headers = new StringBuilder();
1652-
Socket targetConnection = null;
16531658
InputStream ccis = clientConnection.getInputStream();
16541659
OutputStream ccos = clientConnection.getOutputStream();
16551660
Writer w = new OutputStreamWriter(
@@ -1769,28 +1774,44 @@ public void run() {
17691774
end1 = new CompletableFuture<>());
17701775
Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-',
17711776
end2 = new CompletableFuture<>());
1772-
end = CompletableFuture.allOf(end1, end2);
1777+
var end11 = end1.whenComplete((r, t) -> exceptionally(end2, t));
1778+
var end22 = end2.whenComplete((r, t) -> exceptionally(end1, t));
1779+
end = CompletableFuture.allOf(end11, end22);
1780+
Socket tc = targetConnection;
17731781
end.whenComplete(
17741782
(r,t) -> {
17751783
try { toClose.close(); } catch (IOException x) { }
1784+
try { tc.close(); } catch (IOException x) { }
17761785
finally {connectionCFs.remove(end);}
17771786
});
17781787
connectionCFs.add(end);
1788+
targetConnection = clientConnection = null;
17791789
t1.start();
17801790
t2.start();
17811791
}
17821792
} catch (Throwable ex) {
1783-
try {
1784-
ss.close();
1785-
} catch (IOException ex1) {
1786-
ex.addSuppressed(ex1);
1787-
}
1793+
close(clientConnection, ex);
1794+
close(targetConnection, ex);
1795+
close(ss, ex);
17881796
ex.printStackTrace(System.err);
17891797
} finally {
17901798
System.out.println(now() + "Tunnel: exiting (stopped=" + stopped + ")");
17911799
connectionCFs.forEach(cf -> cf.complete(null));
17921800
}
17931801
}
1802+
1803+
void exceptionally(CompletableFuture<?> cf, Throwable t) {
1804+
if (t != null) cf.completeExceptionally(t);
1805+
}
1806+
1807+
void close(Closeable c, Throwable e) {
1808+
if (c == null) return;
1809+
try {
1810+
c.close();
1811+
} catch (IOException x) {
1812+
e.addSuppressed(x);
1813+
}
1814+
}
17941815
}
17951816

17961817
/**

0 commit comments

Comments
 (0)