Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/net/Socket/Timeouts.java
41149 views
1
/*
2
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @bug 8221481
27
* @library /test/lib
28
* @build jdk.test.lib.Utils
29
* @run testng/timeout=180 Timeouts
30
* @summary Test Socket timeouts
31
*/
32
33
import java.io.Closeable;
34
import java.io.IOException;
35
import java.io.InputStream;
36
import java.io.OutputStream;
37
import java.net.ConnectException;
38
import java.net.InetAddress;
39
import java.net.InetSocketAddress;
40
import java.net.ServerSocket;
41
import java.net.Socket;
42
import java.net.SocketAddress;
43
import java.net.SocketException;
44
import java.net.SocketTimeoutException;
45
import java.util.concurrent.Executors;
46
import java.util.concurrent.ExecutionException;
47
import java.util.concurrent.ExecutorService;
48
import java.util.concurrent.Future;
49
import java.util.concurrent.ScheduledExecutorService;
50
import java.util.concurrent.TimeUnit;
51
52
import org.testng.annotations.Test;
53
import static org.testng.Assert.*;
54
import jdk.test.lib.Utils;
55
56
@Test
57
public class Timeouts {
58
59
/**
60
* Test timed connect where connection is established
61
*/
62
public void testTimedConnect1() throws IOException {
63
try (ServerSocket ss = boundServerSocket()) {
64
try (Socket s = new Socket()) {
65
s.connect(ss.getLocalSocketAddress(), 2000);
66
}
67
}
68
}
69
70
/**
71
* Test timed connect where connection is refused
72
*/
73
public void testTimedConnect2() throws IOException {
74
try (Socket s = new Socket()) {
75
SocketAddress remote = Utils.refusingEndpoint();
76
try {
77
s.connect(remote, 10000);
78
} catch (ConnectException expected) { }
79
}
80
}
81
82
/**
83
* Test connect with a timeout of Integer.MAX_VALUE
84
*/
85
public void testTimedConnect3() throws IOException {
86
try (ServerSocket ss = boundServerSocket()) {
87
try (Socket s = new Socket()) {
88
s.connect(ss.getLocalSocketAddress(), Integer.MAX_VALUE);
89
}
90
}
91
}
92
93
/**
94
* Test connect with a negative timeout.
95
*/
96
public void testTimedConnect4() throws IOException {
97
try (ServerSocket ss = boundServerSocket()) {
98
try (Socket s = new Socket()) {
99
expectThrows(IllegalArgumentException.class,
100
() -> s.connect(ss.getLocalSocketAddress(), -1));
101
}
102
}
103
}
104
105
/**
106
* Test timed read where the read succeeds immediately
107
*/
108
public void testTimedRead1() throws IOException {
109
withConnection((s1, s2) -> {
110
s1.getOutputStream().write(99);
111
s2.setSoTimeout(30*1000);
112
int b = s2.getInputStream().read();
113
assertTrue(b == 99);
114
});
115
}
116
117
/**
118
* Test timed read where the read succeeds after a delay
119
*/
120
public void testTimedRead2() throws IOException {
121
withConnection((s1, s2) -> {
122
scheduleWrite(s1.getOutputStream(), 99, 2000);
123
s2.setSoTimeout(30*1000);
124
int b = s2.getInputStream().read();
125
assertTrue(b == 99);
126
});
127
}
128
129
/**
130
* Test timed read where the read times out
131
*/
132
public void testTimedRead3() throws IOException {
133
withConnection((s1, s2) -> {
134
s2.setSoTimeout(2000);
135
long startMillis = millisTime();
136
expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
137
int timeout = s2.getSoTimeout();
138
checkDuration(startMillis, timeout-100, timeout+2000);
139
});
140
}
141
142
/**
143
* Test timed read that succeeds after a previous read has timed out
144
*/
145
public void testTimedRead4() throws IOException {
146
withConnection((s1, s2) -> {
147
s2.setSoTimeout(2000);
148
expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
149
s1.getOutputStream().write(99);
150
int b = s2.getInputStream().read();
151
assertTrue(b == 99);
152
});
153
}
154
155
/**
156
* Test timed read that succeeds after a previous read has timed out and
157
* after a short delay
158
*/
159
public void testTimedRead5() throws IOException {
160
withConnection((s1, s2) -> {
161
s2.setSoTimeout(2000);
162
expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
163
s2.setSoTimeout(30*3000);
164
scheduleWrite(s1.getOutputStream(), 99, 2000);
165
int b = s2.getInputStream().read();
166
assertTrue(b == 99);
167
});
168
}
169
170
/**
171
* Test untimed read that succeeds after a previous read has timed out
172
*/
173
public void testTimedRead6() throws IOException {
174
withConnection((s1, s2) -> {
175
s2.setSoTimeout(2000);
176
expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
177
s1.getOutputStream().write(99);
178
s2.setSoTimeout(0);
179
int b = s2.getInputStream().read();
180
assertTrue(b == 99);
181
});
182
}
183
184
/**
185
* Test untimed read that succeeds after a previous read has timed out and
186
* after a short delay
187
*/
188
public void testTimedRead7() throws IOException {
189
withConnection((s1, s2) -> {
190
s2.setSoTimeout(2000);
191
expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
192
scheduleWrite(s1.getOutputStream(), 99, 2000);
193
s2.setSoTimeout(0);
194
int b = s2.getInputStream().read();
195
assertTrue(b == 99);
196
});
197
}
198
199
/**
200
* Test async close of timed read
201
*/
202
public void testTimedRead8() throws IOException {
203
withConnection((s1, s2) -> {
204
s2.setSoTimeout(30*1000);
205
scheduleClose(s2, 2000);
206
expectThrows(SocketException.class, () -> s2.getInputStream().read());
207
});
208
}
209
210
/**
211
* Test read with a timeout of Integer.MAX_VALUE
212
*/
213
public void testTimedRead9() throws IOException {
214
withConnection((s1, s2) -> {
215
scheduleWrite(s1.getOutputStream(), 99, 2000);
216
s2.setSoTimeout(Integer.MAX_VALUE);
217
int b = s2.getInputStream().read();
218
assertTrue(b == 99);
219
});
220
}
221
222
/**
223
* Test writing after a timed read.
224
*/
225
public void testTimedWrite1() throws IOException {
226
withConnection((s1, s2) -> {
227
s1.getOutputStream().write(99);
228
s2.setSoTimeout(3000);
229
int b = s2.getInputStream().read();
230
assertTrue(b == 99);
231
232
// schedule thread to read s1 to EOF
233
scheduleReadToEOF(s1.getInputStream(), 3000);
234
235
// write a lot so that write blocks
236
byte[] data = new byte[128*1024];
237
for (int i = 0; i < 100; i++) {
238
s2.getOutputStream().write(data);
239
}
240
});
241
}
242
243
/**
244
* Test async close of writer (after a timed read).
245
*/
246
public void testTimedWrite2() throws IOException {
247
withConnection((s1, s2) -> {
248
s1.getOutputStream().write(99);
249
s2.setSoTimeout(3000);
250
int b = s2.getInputStream().read();
251
assertTrue(b == 99);
252
253
// schedule s2 to be be closed
254
scheduleClose(s2, 3000);
255
256
// write a lot so that write blocks
257
byte[] data = new byte[128*1024];
258
try {
259
while (true) {
260
s2.getOutputStream().write(data);
261
}
262
} catch (SocketException expected) { }
263
});
264
}
265
266
/**
267
* Test timed accept where a connection is established immediately
268
*/
269
public void testTimedAccept1() throws IOException {
270
Socket s1 = null;
271
Socket s2 = null;
272
try (ServerSocket ss = boundServerSocket()) {
273
s1 = new Socket();
274
s1.connect(ss.getLocalSocketAddress());
275
ss.setSoTimeout(30*1000);
276
s2 = ss.accept();
277
} finally {
278
if (s1 != null) s1.close();
279
if (s2 != null) s2.close();
280
}
281
}
282
283
/**
284
* Test timed accept where a connection is established after a short delay
285
*/
286
public void testTimedAccept2() throws IOException {
287
try (ServerSocket ss = boundServerSocket()) {
288
ss.setSoTimeout(30*1000);
289
scheduleConnect(ss.getLocalSocketAddress(), 2000);
290
Socket s = ss.accept();
291
s.close();
292
}
293
}
294
295
/**
296
* Test timed accept where the accept times out
297
*/
298
public void testTimedAccept3() throws IOException {
299
try (ServerSocket ss = boundServerSocket()) {
300
ss.setSoTimeout(2000);
301
long startMillis = millisTime();
302
try {
303
Socket s = ss.accept();
304
s.close();
305
fail();
306
} catch (SocketTimeoutException expected) {
307
int timeout = ss.getSoTimeout();
308
checkDuration(startMillis, timeout-100, timeout+2000);
309
}
310
}
311
}
312
313
/**
314
* Test timed accept where a connection is established immediately after a
315
* previous accept timed out.
316
*/
317
public void testTimedAccept4() throws IOException {
318
try (ServerSocket ss = boundServerSocket()) {
319
ss.setSoTimeout(2000);
320
try {
321
Socket s = ss.accept();
322
s.close();
323
fail();
324
} catch (SocketTimeoutException expected) { }
325
try (Socket s1 = new Socket()) {
326
s1.connect(ss.getLocalSocketAddress());
327
Socket s2 = ss.accept();
328
s2.close();
329
}
330
}
331
}
332
333
/**
334
* Test untimed accept where a connection is established after a previous
335
* accept timed out
336
*/
337
public void testTimedAccept5() throws IOException {
338
try (ServerSocket ss = boundServerSocket()) {
339
ss.setSoTimeout(2000);
340
try {
341
Socket s = ss.accept();
342
s.close();
343
fail();
344
} catch (SocketTimeoutException expected) { }
345
ss.setSoTimeout(0);
346
try (Socket s1 = new Socket()) {
347
s1.connect(ss.getLocalSocketAddress());
348
Socket s2 = ss.accept();
349
s2.close();
350
}
351
}
352
}
353
354
/**
355
* Test untimed accept where a connection is established after a previous
356
* accept timed out and after a short delay
357
*/
358
public void testTimedAccept6() throws IOException {
359
try (ServerSocket ss = boundServerSocket()) {
360
ss.setSoTimeout(2000);
361
try {
362
Socket s = ss.accept();
363
s.close();
364
fail();
365
} catch (SocketTimeoutException expected) { }
366
ss.setSoTimeout(0);
367
scheduleConnect(ss.getLocalSocketAddress(), 2000);
368
Socket s = ss.accept();
369
s.close();
370
}
371
}
372
373
/**
374
* Test async close of a timed accept
375
*/
376
public void testTimedAccept7() throws IOException {
377
try (ServerSocket ss = boundServerSocket()) {
378
ss.setSoTimeout(30*1000);
379
long delay = 2000;
380
scheduleClose(ss, delay);
381
long startMillis = millisTime();
382
try {
383
ss.accept().close();
384
fail();
385
} catch (SocketException expected) {
386
checkDuration(startMillis, delay-100, delay+2000);
387
}
388
}
389
}
390
391
/**
392
* Test timed accept with the thread interrupt status set.
393
*/
394
public void testTimedAccept8() throws IOException {
395
try (ServerSocket ss = boundServerSocket()) {
396
ss.setSoTimeout(2000);
397
Thread.currentThread().interrupt();
398
long startMillis = millisTime();
399
try {
400
Socket s = ss.accept();
401
s.close();
402
fail();
403
} catch (SocketTimeoutException expected) {
404
// accept should have blocked for 2 seconds
405
int timeout = ss.getSoTimeout();
406
checkDuration(startMillis, timeout-100, timeout+2000);
407
assertTrue(Thread.currentThread().isInterrupted());
408
} finally {
409
Thread.interrupted(); // clear interrupt status
410
}
411
}
412
}
413
414
/**
415
* Test interrupt of thread blocked in timed accept.
416
*/
417
public void testTimedAccept9() throws IOException {
418
try (ServerSocket ss = boundServerSocket()) {
419
ss.setSoTimeout(4000);
420
// interrupt thread after 1 second
421
Future<?> interrupter = scheduleInterrupt(Thread.currentThread(), 1000);
422
long startMillis = millisTime();
423
try {
424
Socket s = ss.accept(); // should block for 4 seconds
425
s.close();
426
fail();
427
} catch (SocketTimeoutException expected) {
428
// accept should have blocked for 4 seconds
429
int timeout = ss.getSoTimeout();
430
checkDuration(startMillis, timeout-100, timeout+2000);
431
assertTrue(Thread.currentThread().isInterrupted());
432
} finally {
433
interrupter.cancel(true);
434
Thread.interrupted(); // clear interrupt status
435
}
436
}
437
}
438
439
/**
440
* Test two threads blocked in timed accept where no connection is established.
441
*/
442
public void testTimedAccept10() throws Exception {
443
ExecutorService pool = Executors.newFixedThreadPool(2);
444
try (ServerSocket ss = boundServerSocket()) {
445
ss.setSoTimeout(4000);
446
447
long startMillis = millisTime();
448
449
Future<Socket> result1 = pool.submit(ss::accept);
450
Future<Socket> result2 = pool.submit(ss::accept);
451
452
// both tasks should complete with SocketTimeoutException
453
Throwable e = expectThrows(ExecutionException.class, result1::get);
454
assertTrue(e.getCause() instanceof SocketTimeoutException);
455
e = expectThrows(ExecutionException.class, result2::get);
456
assertTrue(e.getCause() instanceof SocketTimeoutException);
457
458
// should get here in 4 seconds, not 8 seconds
459
int timeout = ss.getSoTimeout();
460
checkDuration(startMillis, timeout-100, timeout+2000);
461
} finally {
462
pool.shutdown();
463
}
464
}
465
466
/**
467
* Test two threads blocked in timed accept where one connection is established.
468
*/
469
public void testTimedAccept11() throws Exception {
470
ExecutorService pool = Executors.newFixedThreadPool(2);
471
try (ServerSocket ss = boundServerSocket()) {
472
ss.setSoTimeout(4000);
473
474
long startMillis = millisTime();
475
476
Future<Socket> result1 = pool.submit(ss::accept);
477
Future<Socket> result2 = pool.submit(ss::accept);
478
479
// establish connection after 2 seconds
480
scheduleConnect(ss.getLocalSocketAddress(), 2000);
481
482
// one task should have accepted the connection, the other should
483
// have completed with SocketTimeoutException
484
Socket s1 = null;
485
try {
486
s1 = result1.get();
487
s1.close();
488
} catch (ExecutionException e) {
489
assertTrue(e.getCause() instanceof SocketTimeoutException);
490
}
491
Socket s2 = null;
492
try {
493
s2 = result2.get();
494
s2.close();
495
} catch (ExecutionException e) {
496
assertTrue(e.getCause() instanceof SocketTimeoutException);
497
}
498
assertTrue((s1 != null) ^ (s2 != null));
499
500
// should get here in 4 seconds, not 8 seconds
501
int timeout = ss.getSoTimeout();
502
checkDuration(startMillis, timeout-100, timeout+2000);
503
} finally {
504
pool.shutdown();
505
}
506
}
507
508
/**
509
* Test Socket setSoTimeout with a negative timeout.
510
*/
511
@Test(expectedExceptions = { IllegalArgumentException.class })
512
public void testBadTimeout1() throws IOException {
513
try (Socket s = new Socket()) {
514
s.setSoTimeout(-1);
515
}
516
}
517
518
/**
519
* Test ServerSocket setSoTimeout with a negative timeout.
520
*/
521
@Test(expectedExceptions = { IllegalArgumentException.class })
522
public void testBadTimeout2() throws IOException {
523
try (ServerSocket ss = new ServerSocket()) {
524
ss.setSoTimeout(-1);
525
}
526
}
527
528
/**
529
* Returns a ServerSocket bound to a port on the loopback address
530
*/
531
static ServerSocket boundServerSocket() throws IOException {
532
var loopback = InetAddress.getLoopbackAddress();
533
ServerSocket ss = new ServerSocket();
534
ss.bind(new InetSocketAddress(loopback, 0));
535
return ss;
536
}
537
538
/**
539
* An operation that accepts two arguments and may throw IOException
540
*/
541
interface ThrowingBiConsumer<T, U> {
542
void accept(T t, U u) throws IOException;
543
}
544
545
/**
546
* Invokes the consumer with a connected pair of sockets
547
*/
548
static void withConnection(ThrowingBiConsumer<Socket, Socket> consumer)
549
throws IOException
550
{
551
Socket s1 = null;
552
Socket s2 = null;
553
try (ServerSocket ss = boundServerSocket()) {
554
s1 = new Socket();
555
s1.connect(ss.getLocalSocketAddress());
556
s2 = ss.accept();
557
consumer.accept(s1, s2);
558
} finally {
559
if (s1 != null) s1.close();
560
if (s2 != null) s2.close();
561
}
562
}
563
564
/**
565
* Schedule c to be closed after a delay
566
*/
567
static void scheduleClose(Closeable c, long delay) {
568
schedule(() -> {
569
try {
570
c.close();
571
} catch (IOException ioe) { }
572
}, delay);
573
}
574
575
/**
576
* Schedule thread to be interrupted after a delay
577
*/
578
static Future<?> scheduleInterrupt(Thread thread, long delay) {
579
return schedule(() -> thread.interrupt(), delay);
580
}
581
582
/**
583
* Schedule a thread to connect to the given end point after a delay
584
*/
585
static void scheduleConnect(SocketAddress remote, long delay) {
586
schedule(() -> {
587
try (Socket s = new Socket()) {
588
s.connect(remote);
589
} catch (IOException ioe) { }
590
}, delay);
591
}
592
593
/**
594
* Schedule a thread to read to EOF after a delay
595
*/
596
static void scheduleReadToEOF(InputStream in, long delay) {
597
schedule(() -> {
598
byte[] bytes = new byte[8192];
599
try {
600
while (in.read(bytes) != -1) { }
601
} catch (IOException ioe) { }
602
}, delay);
603
}
604
605
/**
606
* Schedule a thread to write after a delay
607
*/
608
static void scheduleWrite(OutputStream out, byte[] data, long delay) {
609
schedule(() -> {
610
try {
611
out.write(data);
612
} catch (IOException ioe) { }
613
}, delay);
614
}
615
static void scheduleWrite(OutputStream out, int b, long delay) {
616
scheduleWrite(out, new byte[] { (byte)b }, delay);
617
}
618
619
static Future<?> schedule(Runnable task, long delay) {
620
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
621
try {
622
return executor.schedule(task, delay, TimeUnit.MILLISECONDS);
623
} finally {
624
executor.shutdown();
625
}
626
}
627
628
/**
629
* Returns the current time in milliseconds.
630
*/
631
private static long millisTime() {
632
long now = System.nanoTime();
633
return TimeUnit.MILLISECONDS.convert(now, TimeUnit.NANOSECONDS);
634
}
635
636
/**
637
* Check the duration of a task
638
* @param start start time, in milliseconds
639
* @param min minimum expected duration, in milliseconds
640
* @param max maximum expected duration, in milliseconds
641
* @return the duration (now - start), in milliseconds
642
*/
643
private static long checkDuration(long start, long min, long max) {
644
long duration = millisTime() - start;
645
assertTrue(duration >= min,
646
"Duration " + duration + "ms, expected >= " + min + "ms");
647
assertTrue(duration <= max,
648
"Duration " + duration + "ms, expected <= " + max + "ms");
649
return duration;
650
}
651
}
652
653