36
36
import com .sun .net .httpserver .HttpServer ;
37
37
import com .sun .net .httpserver .HttpsConfigurator ;
38
38
import com .sun .net .httpserver .HttpsServer ;
39
+ import jdk .internal .net .http .common .OperationTrackers ;
39
40
import jdk .test .lib .net .SimpleSSLContext ;
40
41
import org .testng .annotations .AfterTest ;
41
42
import org .testng .annotations .BeforeTest ;
@@ -100,6 +101,16 @@ public class ResponsePublisher implements HttpServerAdapters {
100
101
// a shared executor helps reduce the amount of threads created by the test
101
102
static final Executor executor = Executors .newCachedThreadPool ();
102
103
104
+ static final long start = System .nanoTime ();
105
+
106
+ public static String now () {
107
+ long now = System .nanoTime () - start ;
108
+ long secs = now / 1000_000_000 ;
109
+ long mill = (now % 1000_000_000 ) / 1000_000 ;
110
+ long nan = now % 1000_000 ;
111
+ return String .format ("[%d s, %d ms, %d ns] " , secs , mill , nan );
112
+ }
113
+
103
114
interface BHS extends Supplier <BodyHandler <Publisher <List <ByteBuffer >>>> {
104
115
static BHS of (BHS impl , String name ) {
105
116
return new BHSImpl (impl , name );
@@ -216,6 +227,12 @@ public void testExceptions(String uri, boolean sameClient, BHS handlers) throws
216
227
// Get the final result and compare it with the expected body
217
228
String body = ofString .getBody ().toCompletableFuture ().get ();
218
229
assertEquals (body , "" );
230
+ // ensure client closes before next iteration
231
+ if (!sameClient ) {
232
+ var tracker = TRACKER .getTracker (client );
233
+ client = null ;
234
+ clientCleanup (tracker );
235
+ }
219
236
}
220
237
}
221
238
@@ -239,6 +256,12 @@ public void testNoBody(String uri, boolean sameClient, BHS handlers) throws Exce
239
256
// Get the final result and compare it with the expected body
240
257
String body = ofString .getBody ().toCompletableFuture ().get ();
241
258
assertEquals (body , "" );
259
+ // ensure client closes before next iteration
260
+ if (!sameClient ) {
261
+ var tracker = TRACKER .getTracker (client );
262
+ client = null ;
263
+ clientCleanup (tracker );
264
+ }
242
265
}
243
266
}
244
267
@@ -265,6 +288,12 @@ public void testNoBodyAsync(String uri, boolean sameClient, BHS handlers) throws
265
288
});
266
289
// Get the final result and compare it with the expected body
267
290
assertEquals (result .get (), "" );
291
+ // ensure client closes before next iteration
292
+ if (!sameClient ) {
293
+ var tracker = TRACKER .getTracker (client );
294
+ client = null ;
295
+ clientCleanup (tracker );
296
+ }
268
297
}
269
298
}
270
299
@@ -288,6 +317,12 @@ public void testAsString(String uri, boolean sameClient, BHS handlers) throws Ex
288
317
// Get the final result and compare it with the expected body
289
318
String body = ofString .getBody ().toCompletableFuture ().get ();
290
319
assertEquals (body , WITH_BODY );
320
+ // ensure client closes before next iteration
321
+ if (!sameClient ) {
322
+ var tracker = TRACKER .getTracker (client );
323
+ client = null ;
324
+ clientCleanup (tracker );
325
+ }
291
326
}
292
327
}
293
328
@@ -314,6 +349,12 @@ public void testAsStringAsync(String uri, boolean sameClient, BHS handlers) thro
314
349
// Get the final result and compare it with the expected body
315
350
String body = result .get ();
316
351
assertEquals (body , WITH_BODY );
352
+ // ensure client closes before next iteration
353
+ if (!sameClient ) {
354
+ var tracker = TRACKER .getTracker (client );
355
+ client = null ;
356
+ clientCleanup (tracker );
357
+ }
317
358
}
318
359
}
319
360
@@ -451,6 +492,23 @@ public void teardown() throws Exception {
451
492
}
452
493
}
453
494
495
+ // Wait for the client to be garbage collected.
496
+ // we use the ReferenceTracker API rather than HttpClient::close here,
497
+ // because we want to get some diagnosis if a client doesn't release
498
+ // its resources and terminates as expected
499
+ // By using the ReferenceTracker, we will get some diagnosis about what
500
+ // is keeping the client alive if it doesn't get GC'ed within the
501
+ // expected time frame.
502
+ public void clientCleanup (OperationTrackers .Tracker tracker ){
503
+ System .gc ();
504
+ System .out .println (now () + "waiting for client to shutdown: " + tracker .getName ());
505
+ System .err .println (now () + "waiting for client to shutdown: " + tracker .getName ());
506
+ var error = TRACKER .check (tracker , 10000 );
507
+ if (error != null ) throw error ;
508
+ System .out .println (now () + "client shutdown normally: " + tracker .getName ());
509
+ System .err .println (now () + "client shutdown normally: " + tracker .getName ());
510
+ }
511
+
454
512
static final String WITH_BODY = "Lorem ipsum dolor sit amet, consectetur" +
455
513
" adipiscing elit, sed do eiusmod tempor incididunt ut labore et" +
456
514
" dolore magna aliqua. Ut enim ad minim veniam, quis nostrud" +
0 commit comments