25 * @test |
25 * @test |
26 * @summary Verify that dependent synchronous actions added before the CF |
26 * @summary Verify that dependent synchronous actions added before the CF |
27 * completes are executed either asynchronously in an executor when the |
27 * completes are executed either asynchronously in an executor when the |
28 * CF later completes, or in the user thread that joins. |
28 * CF later completes, or in the user thread that joins. |
29 * @library /lib/testlibrary http2/server |
29 * @library /lib/testlibrary http2/server |
30 * @build jdk.testlibrary.SimpleSSLContext HttpServerAdapters ThrowingPublishers |
30 * @build jdk.testlibrary.SimpleSSLContext HttpServerAdapters DependentActionsTest |
31 * @modules java.base/sun.net.www.http |
31 * @modules java.base/sun.net.www.http |
32 * java.net.http/jdk.internal.net.http.common |
32 * java.net.http/jdk.internal.net.http.common |
33 * java.net.http/jdk.internal.net.http.frame |
33 * java.net.http/jdk.internal.net.http.frame |
34 * java.net.http/jdk.internal.net.http.hpack |
34 * java.net.http/jdk.internal.net.http.hpack |
35 * @run testng/othervm -Djdk.internal.httpclient.debug=true DependentActionsTest |
35 * @run testng/othervm -Djdk.internal.httpclient.debug=true DependentActionsTest |
80 import java.util.concurrent.Semaphore; |
80 import java.util.concurrent.Semaphore; |
81 import java.util.concurrent.atomic.AtomicBoolean; |
81 import java.util.concurrent.atomic.AtomicBoolean; |
82 import java.util.concurrent.atomic.AtomicLong; |
82 import java.util.concurrent.atomic.AtomicLong; |
83 import java.util.concurrent.atomic.AtomicReference; |
83 import java.util.concurrent.atomic.AtomicReference; |
84 import java.util.function.Consumer; |
84 import java.util.function.Consumer; |
|
85 import java.util.function.Predicate; |
85 import java.util.function.Supplier; |
86 import java.util.function.Supplier; |
86 import java.util.stream.Collectors; |
87 import java.util.stream.Collectors; |
87 import java.util.stream.Stream; |
88 import java.util.stream.Stream; |
88 |
89 |
89 import static java.lang.System.out; |
90 import static java.lang.System.out; |
90 import static java.lang.String.format; |
91 import static java.lang.String.format; |
|
92 import static java.util.stream.Collectors.toList; |
91 import static org.testng.Assert.assertEquals; |
93 import static org.testng.Assert.assertEquals; |
92 import static org.testng.Assert.assertTrue; |
94 import static org.testng.Assert.assertTrue; |
93 |
95 |
94 public class DependentActionsTest implements HttpServerAdapters { |
96 public class DependentActionsTest implements HttpServerAdapters { |
95 |
97 |
372 final List<String> extractString(HttpResponse<String> resp) { |
374 final List<String> extractString(HttpResponse<String> resp) { |
373 return List.of(resp.body()); |
375 return List.of(resp.body()); |
374 } |
376 } |
375 |
377 |
376 final List<String> extractStream(HttpResponse<Stream<String>> resp) { |
378 final List<String> extractStream(HttpResponse<Stream<String>> resp) { |
377 return resp.body().collect(Collectors.toList()); |
379 return resp.body().collect(toList()); |
378 } |
380 } |
379 |
381 |
380 final List<String> extractInputStream(HttpResponse<InputStream> resp) { |
382 final List<String> extractInputStream(HttpResponse<InputStream> resp) { |
381 try (InputStream is = resp.body()) { |
383 try (InputStream is = resp.body()) { |
382 return new BufferedReader(new InputStreamReader(is)) |
384 return new BufferedReader(new InputStreamReader(is)) |
383 .lines().collect(Collectors.toList()); |
385 .lines().collect(toList()); |
384 } catch (IOException x) { |
386 } catch (IOException x) { |
385 throw new CompletionException(x); |
387 throw new CompletionException(x); |
386 } |
388 } |
387 } |
389 } |
388 |
390 |
397 return s.filter((f) -> f.getClassName().contains(name)) |
399 return s.filter((f) -> f.getClassName().contains(name)) |
398 .filter((f) -> f.getDeclaringClass().getModule().equals(HttpClient.class.getModule())) |
400 .filter((f) -> f.getDeclaringClass().getModule().equals(HttpClient.class.getModule())) |
399 .findFirst(); |
401 .findFirst(); |
400 } |
402 } |
401 |
403 |
|
404 static final Predicate<StackFrame> DAT = sfe -> |
|
405 sfe.getClassName().startsWith("DependentActionsTest"); |
|
406 static final Predicate<StackFrame> JUC = sfe -> |
|
407 sfe.getClassName().startsWith("java.util.concurrent"); |
|
408 static final Predicate<StackFrame> JLT = sfe -> |
|
409 sfe.getClassName().startsWith("java.lang.Thread"); |
|
410 static final Predicate<StackFrame> NotDATorJUCorJLT = Predicate.not(DAT.or(JUC).or(JLT)); |
|
411 |
|
412 |
402 <T> void checkThreadAndStack(Thread thread, |
413 <T> void checkThreadAndStack(Thread thread, |
403 AtomicReference<RuntimeException> failed, |
414 AtomicReference<RuntimeException> failed, |
404 T result, |
415 T result, |
405 Throwable error) { |
416 Throwable error) { |
406 if (Thread.currentThread() == thread) { |
417 //failed.set(new RuntimeException("Dependant action was executed in " + thread)); |
407 //failed.set(new RuntimeException("Dependant action was executed in " + thread)); |
418 List<StackFrame> otherFrames = WALKER.walk(s -> s.filter(NotDATorJUCorJLT).collect(toList())); |
408 List<StackFrame> httpStack = WALKER.walk(s -> s.filter(f -> f.getDeclaringClass() |
419 if (!otherFrames.isEmpty()) { |
409 .getModule().equals(HttpClient.class.getModule())) |
420 System.out.println("Found unexpected trace: "); |
410 .collect(Collectors.toList())); |
421 otherFrames.forEach(f -> System.out.printf("\t%s%n", f)); |
411 if (!httpStack.isEmpty()) { |
422 failed.set(new RuntimeException("Dependant action has unexpected frame in " + |
412 System.out.println("Found unexpected trace: "); |
423 Thread.currentThread() + ": " + otherFrames.get(0))); |
413 httpStack.forEach(f -> System.out.printf("\t%s%n", f)); |
424 |
414 failed.set(new RuntimeException("Dependant action has unexpected frame in " + |
|
415 Thread.currentThread() + ": " + httpStack.get(0))); |
|
416 |
|
417 } |
|
418 return; |
|
419 } else if (System.getSecurityManager() != null) { |
|
420 Optional<StackFrame> sf = WALKER.walk(s -> findFrame(s, "PrivilegedRunnable")); |
|
421 if (!sf.isPresent()) { |
|
422 failed.set(new RuntimeException("Dependant action does not have expected frame in " |
|
423 + Thread.currentThread())); |
|
424 return; |
|
425 } else { |
|
426 System.out.println("Found expected frame: " + sf.get()); |
|
427 } |
|
428 } else { |
|
429 List<StackFrame> httpStack = WALKER.walk(s -> s.filter(f -> f.getDeclaringClass() |
|
430 .getModule().equals(HttpClient.class.getModule())) |
|
431 .collect(Collectors.toList())); |
|
432 if (!httpStack.isEmpty()) { |
|
433 System.out.println("Found unexpected trace: "); |
|
434 httpStack.forEach(f -> System.out.printf("\t%s%n", f)); |
|
435 failed.set(new RuntimeException("Dependant action has unexpected frame in " + |
|
436 Thread.currentThread() + ": " + httpStack.get(0))); |
|
437 |
|
438 } |
|
439 } |
425 } |
440 } |
426 } |
441 |
427 |
442 <T> void finish(Where w, CompletableFuture<HttpResponse<T>> cf, |
428 <T> void finish(Where w, CompletableFuture<HttpResponse<T>> cf, |
443 Staller staller, |
429 Staller staller, |
618 http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); |
604 http2TestServer.addHandler(h2_fixedLengthHandler, "/http2/fixed"); |
619 http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); |
605 http2TestServer.addHandler(h2_chunkedHandler, "/http2/chunk"); |
620 http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/x"; |
606 http2URI_fixed = "http://" + http2TestServer.serverAuthority() + "/http2/fixed/x"; |
621 http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/x"; |
607 http2URI_chunk = "http://" + http2TestServer.serverAuthority() + "/http2/chunk/x"; |
622 |
608 |
623 https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, 0)); |
609 https2TestServer = HttpTestServer.of(new Http2TestServer("localhost", true, sslContext)); |
624 https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); |
610 https2TestServer.addHandler(h2_fixedLengthHandler, "/https2/fixed"); |
625 https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); |
611 https2TestServer.addHandler(h2_chunkedHandler, "/https2/chunk"); |
626 https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/x"; |
612 https2URI_fixed = "https://" + https2TestServer.serverAuthority() + "/https2/fixed/x"; |
627 https2URI_chunk = "https://" + https2TestServer.serverAuthority() + "/https2/chunk/x"; |
613 https2URI_chunk = "https://" + https2TestServer.serverAuthority() + "/https2/chunk/x"; |
628 |
614 |