mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-26 05:18:05 +00:00
8378163: test/jdk/java/net/httpclient/*.java: convert tests that use ITestContext to JUnit
Reviewed-by: vyazici
This commit is contained in:
parent
932f28c69b
commit
c1f8209cb2
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* This is not a test. Actual tests are implemented by concrete subclasses.
|
||||
* The abstract class AbstractThrowingPushPromises provides a base framework
|
||||
* to test what happens when push promise handlers and their
|
||||
@ -62,7 +62,6 @@ import java.net.http.HttpResponse.BodySubscriber;
|
||||
import java.net.http.HttpResponse.PushPromiseHandler;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -104,7 +103,6 @@ import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public abstract class AbstractThrowingPushPromises implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
@ -193,14 +191,9 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
|
||||
|
||||
@AfterAll
|
||||
static final void printFailedTests() {
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
// Exceptions should already have been added to FAILURES
|
||||
// var failed = context.getFailedTests().getAllResults().stream()
|
||||
// .collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable));
|
||||
// FAILURES.putAll(failed);
|
||||
|
||||
out.printf("%n%sCreated %d servers and %d clients%n",
|
||||
now(), serverCount.get(), clientCount.get());
|
||||
if (FAILURES.isEmpty()) return;
|
||||
@ -339,7 +332,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
HttpRequest req = request(uri);
|
||||
|
||||
BodyHandler<Stream<String>> handler =
|
||||
new ThrowingBodyHandler((w) -> {},
|
||||
new ThrowingBodyHandler<>((w) -> {},
|
||||
BodyHandlers.ofLines());
|
||||
Map<HttpRequest, CompletableFuture<HttpResponse<Stream<String>>>> pushPromises =
|
||||
new ConcurrentHashMap<>();
|
||||
@ -387,9 +380,9 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
}
|
||||
|
||||
// @Test(dataProvider = "variants")
|
||||
protected void testThrowingAsStringImpl(String uri,
|
||||
boolean sameClient,
|
||||
Thrower thrower)
|
||||
void testThrowingAsStringImpl(String uri,
|
||||
boolean sameClient,
|
||||
Thrower thrower)
|
||||
throws Exception
|
||||
{
|
||||
String test = format("testThrowingAsString(%s, %b, %s)",
|
||||
@ -399,7 +392,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
}
|
||||
|
||||
//@Test(dataProvider = "variants")
|
||||
protected void testThrowingAsLinesImpl(String uri,
|
||||
void testThrowingAsLinesImpl(String uri,
|
||||
boolean sameClient,
|
||||
Thrower thrower)
|
||||
throws Exception
|
||||
@ -411,9 +404,9 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
}
|
||||
|
||||
//@Test(dataProvider = "variants")
|
||||
protected void testThrowingAsInputStreamImpl(String uri,
|
||||
boolean sameClient,
|
||||
Thrower thrower)
|
||||
void testThrowingAsInputStreamImpl(String uri,
|
||||
boolean sameClient,
|
||||
Thrower thrower)
|
||||
throws Exception
|
||||
{
|
||||
String test = format("testThrowingAsInputStream(%s, %b, %s)",
|
||||
@ -424,7 +417,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
|
||||
private <T,U> void testThrowing(String name, String uri, boolean sameClient,
|
||||
Supplier<BodyHandler<T>> handlers,
|
||||
Finisher finisher, Thrower thrower)
|
||||
Finisher<T,U> finisher, Thrower thrower)
|
||||
throws Exception
|
||||
{
|
||||
out.printf("%n%s%s%n", now(), name);
|
||||
@ -438,7 +431,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
|
||||
private <T,U> void testThrowing(String uri, boolean sameClient,
|
||||
Supplier<BodyHandler<T>> handlers,
|
||||
Finisher finisher, Thrower thrower)
|
||||
Finisher<T,U> finisher, Thrower thrower)
|
||||
throws Exception
|
||||
{
|
||||
HttpClient client = null;
|
||||
@ -452,7 +445,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
ConcurrentMap<HttpRequest, CompletableFuture<HttpResponse<T>>> promiseMap =
|
||||
new ConcurrentHashMap<>();
|
||||
Supplier<BodyHandler<T>> throwing = () ->
|
||||
new ThrowingBodyHandler(where.select(thrower), handlers.get());
|
||||
new ThrowingBodyHandler<>(where.select(thrower), handlers.get());
|
||||
PushPromiseHandler<T> pushHandler = new ThrowingPromiseHandler<>(
|
||||
where.select(thrower),
|
||||
PushPromiseHandler.of((r) -> throwing.get(), promiseMap));
|
||||
@ -540,7 +533,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
return check(w, reqURI, resp, thrower, promises, extractor);
|
||||
}
|
||||
|
||||
private final <T> List<String> check(Where w, URI reqURI,
|
||||
private <T> List<String> check(Where w, URI reqURI,
|
||||
HttpResponse<T> resp,
|
||||
Thrower thrower,
|
||||
Map<HttpRequest, CompletableFuture<HttpResponse<T>>> promises,
|
||||
@ -697,7 +690,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
|
||||
public BodySubscriber<T> apply(HttpResponse.ResponseInfo rinfo) {
|
||||
throwing.accept(Where.BODY_HANDLER);
|
||||
BodySubscriber<T> subscriber = bodyHandler.apply(rinfo);
|
||||
return new ThrowingBodySubscriber(throwing, subscriber);
|
||||
return new ThrowingBodySubscriber<>(throwing, subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
||||
* @build jdk.test.lib.net.SimpleSSLContext jdk.httpclient.test.lib.common.HttpServerAdapters
|
||||
* ReferenceTracker AggregateRequestBodyTest
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true
|
||||
* -Djdk.httpclient.HttpClient.log=requests,responses,errors,headers,frames
|
||||
* AggregateRequestBodyTest
|
||||
* @summary Tests HttpRequest.BodyPublishers::concat
|
||||
@ -41,7 +41,6 @@ import java.net.http.HttpRequest.BodyPublishers;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -70,40 +69,43 @@ import javax.net.ssl.SSLContext;
|
||||
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import jdk.test.lib.net.URIBuilder;
|
||||
import org.testng.Assert;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static java.lang.System.out;
|
||||
import static java.net.http.HttpClient.Version.HTTP_1_1;
|
||||
import static java.net.http.HttpClient.Version.HTTP_2;
|
||||
import static java.net.http.HttpClient.Version.HTTP_3;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.expectThrows;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer http1TestServer; // HTTP/1.1 ( http )
|
||||
HttpTestServer https1TestServer; // HTTPS/1.1 ( https )
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
URI http1URI;
|
||||
URI https1URI;
|
||||
URI http2URI;
|
||||
URI https2URI;
|
||||
URI http3URI;
|
||||
private static HttpTestServer http1TestServer; // HTTP/1.1 ( http )
|
||||
private static HttpTestServer https1TestServer; // HTTPS/1.1 ( https )
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
private static URI http1URI;
|
||||
private static URI https1URI;
|
||||
private static URI http2URI;
|
||||
private static URI https2URI;
|
||||
private static URI http3URI;
|
||||
|
||||
static final int RESPONSE_CODE = 200;
|
||||
static final int ITERATION_COUNT = 4;
|
||||
@ -123,8 +125,8 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static volatile HttpClient sharedClient;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -150,40 +152,40 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests(ITestContext context) {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
var failed = context.getFailedTests().getAllResults().stream()
|
||||
.collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable));
|
||||
FAILURES.putAll(failed);
|
||||
|
||||
out.printf("%n%sCreated %d servers and %d clients%n",
|
||||
now(), serverCount.get(), clientCount.get());
|
||||
if (FAILURES.isEmpty()) return;
|
||||
@ -201,7 +203,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private URI[] uris() {
|
||||
private static URI[] uris() {
|
||||
return new URI[] {
|
||||
http1URI,
|
||||
https1URI,
|
||||
@ -211,13 +213,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
};
|
||||
}
|
||||
|
||||
static AtomicLong URICOUNT = new AtomicLong();
|
||||
|
||||
@DataProvider(name = "variants")
|
||||
public Object[][] variants(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
return new Object[0][];
|
||||
}
|
||||
public static Object[][] variants() {
|
||||
URI[] uris = uris();
|
||||
Object[][] result = new Object[uris.length * 2][];
|
||||
int i = 0;
|
||||
@ -285,8 +281,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
return s;
|
||||
}
|
||||
|
||||
@DataProvider(name = "sparseContent")
|
||||
Object[][] nulls() {
|
||||
static Object[][] nulls() {
|
||||
return new Object[][] {
|
||||
{"null array", null},
|
||||
{"null element", strings((String)null)},
|
||||
@ -304,8 +299,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@DataProvider(name = "contentLengths")
|
||||
Object[][] contentLengths() {
|
||||
static Object[][] contentLengths() {
|
||||
return new Object[][] {
|
||||
{-1, lengths(-1)},
|
||||
{-42, lengths(-42)},
|
||||
@ -332,8 +326,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name="negativeRequests")
|
||||
Object[][] negativeRequests() {
|
||||
static Object[][] negativeRequests() {
|
||||
return new Object[][] {
|
||||
{0L}, {-1L}, {-2L}, {Long.MIN_VALUE + 1L}, {Long.MIN_VALUE}
|
||||
};
|
||||
@ -492,31 +485,33 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
() -> new AssertionError("Should not happen!"));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "sparseContent") // checks that NPE is thrown
|
||||
@ParameterizedTest // checks that NPE is thrown
|
||||
@MethodSource("nulls")
|
||||
public void testNullPointerException(String description, String[] content) {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testNullPointerException %s%n%n", now(), description);
|
||||
BodyPublisher[] publishers = publishers(content);
|
||||
Assert.assertThrows(NullPointerException.class, () -> BodyPublishers.concat(publishers));
|
||||
Assertions.assertThrows(NullPointerException.class, () -> BodyPublishers.concat(publishers));
|
||||
}
|
||||
|
||||
// Verifies that an empty array creates a "noBody" publisher
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testEmpty%n%n", now());
|
||||
BodyPublisher publisher = BodyPublishers.concat();
|
||||
RequestSubscriber subscriber = new RequestSubscriber();
|
||||
assertEquals(publisher.contentLength(), 0);
|
||||
assertEquals(0, publisher.contentLength());
|
||||
publisher.subscribe(subscriber);
|
||||
subscriber.subscriptionCF.thenAccept(s -> s.request(1));
|
||||
List<ByteBuffer> result = subscriber.resultCF.join();
|
||||
assertEquals(result, List.of());
|
||||
assertEquals(List.of(), result);
|
||||
assertTrue(subscriber.items.isEmpty());
|
||||
}
|
||||
|
||||
// verifies that error emitted by upstream publishers are propagated downstream.
|
||||
@Test(dataProvider = "sparseContent") // nulls are replaced with error publisher
|
||||
@ParameterizedTest // nulls are replaced with error publisher
|
||||
@MethodSource("nulls")
|
||||
public void testOnError(String description, String[] content) {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testOnError %s%n%n", now(), description);
|
||||
final RequestSubscriber subscriber = new RequestSubscriber();
|
||||
final PublishWithError errorPublisher;
|
||||
final BodyPublisher[] publishers;
|
||||
@ -556,13 +551,13 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
publisher.subscribe(subscriber);
|
||||
subscriber.subscriptionCF.thenAccept(s -> s.request(Long.MAX_VALUE));
|
||||
if (errorPublisher.hasErrors()) {
|
||||
CompletionException ce = expectThrows(CompletionException.class,
|
||||
CompletionException ce = Assertions.assertThrows(CompletionException.class,
|
||||
() -> subscriber.resultCF.join());
|
||||
out.println(description + ": got expected " + ce);
|
||||
assertEquals(ce.getCause().getClass(), Exception.class);
|
||||
assertEquals(stringFromBytes(subscriber.items.stream()) + "<error>", result);
|
||||
assertEquals(Exception.class, ce.getCause().getClass());
|
||||
assertEquals(result, stringFromBytes(subscriber.items.stream()) + "<error>");
|
||||
} else {
|
||||
assertEquals(stringFromBytes(subscriber.resultCF.join().stream()), result);
|
||||
assertEquals(result, stringFromBytes(subscriber.resultCF.join().stream()));
|
||||
out.println(description + ": got expected result: " + result);
|
||||
}
|
||||
}
|
||||
@ -570,9 +565,10 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
// Verifies that if an upstream publisher has an unknown length, the
|
||||
// aggregate publisher will have an unknown length as well. Otherwise
|
||||
// the length should be known.
|
||||
@Test(dataProvider = "sparseContent") // nulls are replaced with unknown length
|
||||
@ParameterizedTest // nulls are replaced with unknown length
|
||||
@MethodSource("nulls")
|
||||
public void testUnknownContentLength(String description, String[] content) {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testUnknownContentLength %s%n%n", now(), description);
|
||||
if (content == null) {
|
||||
content = BODIES.toArray(String[]::new);
|
||||
description = "BODIES (known length)";
|
||||
@ -598,9 +594,9 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
length += content[i].length();
|
||||
}
|
||||
}
|
||||
out.printf("testUnknownContentLength(%s): %d%n", description, length);
|
||||
out.printf("%stestUnknownContentLength(%s): %d%n", now(), description, length);
|
||||
BodyPublisher publisher = BodyPublishers.concat(publishers);
|
||||
assertEquals(publisher.contentLength(), length,
|
||||
assertEquals(length, publisher.contentLength(),
|
||||
description.replace("null", "length(-1)"));
|
||||
}
|
||||
|
||||
@ -611,9 +607,10 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
return x.getCause();
|
||||
}
|
||||
|
||||
@Test(dataProvider = "negativeRequests")
|
||||
@ParameterizedTest
|
||||
@MethodSource("negativeRequests")
|
||||
public void testNegativeRequest(long n) {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testNegativeRequest %s%n%n", now(), n);
|
||||
assert n <= 0 : "test for negative request called with n > 0 : " + n;
|
||||
BodyPublisher[] publishers = ContentLengthPublisher.of(List.of(1L, 2L, 3L));
|
||||
BodyPublisher publisher = BodyPublishers.concat(publishers);
|
||||
@ -621,7 +618,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
publisher.subscribe(subscriber);
|
||||
Subscription subscription = subscriber.subscriptionCF.join();
|
||||
subscription.request(n);
|
||||
CompletionException expected = expectThrows(CE, () -> subscriber.resultCF.join());
|
||||
CompletionException expected = Assertions.assertThrows(CE, () -> subscriber.resultCF.join());
|
||||
Throwable cause = completionCause(expected);
|
||||
if (cause instanceof IllegalArgumentException) {
|
||||
System.out.printf("Got expected IAE for %d: %s%n", n, cause);
|
||||
@ -637,7 +634,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
|
||||
@Test
|
||||
public void testPositiveRequests() {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testPositiveRequests%n%n", now());
|
||||
// A composite array of publishers
|
||||
BodyPublisher[] publishers = Stream.of(
|
||||
Stream.of(ofStrings("Lorem", " ", "ipsum", " ")),
|
||||
@ -657,7 +654,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
List<ByteBuffer> list1 = requestSubscriber1.resultCF().join();
|
||||
assertTrue(requestSubscriber1.resultCF().isDone());
|
||||
String result1 = stringFromBytes(list1.stream());
|
||||
assertEquals(result1, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
||||
assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", result1);
|
||||
System.out.println("Got expected sentence with one request: \"%s\"".formatted(result1));
|
||||
|
||||
// Test that we can split our requests call any which way we want
|
||||
@ -675,16 +672,17 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
List<ByteBuffer> list2 = requestSubscriber2.resultCF().join();
|
||||
assertTrue(requestSubscriber2.resultCF().isDone());
|
||||
String result2 = stringFromBytes(list2.stream());
|
||||
assertEquals(result2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
|
||||
assertEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", result2);
|
||||
System.out.println("Got expected sentence with 4 requests: \"%s\"".formatted(result1));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "contentLengths")
|
||||
@ParameterizedTest
|
||||
@MethodSource("contentLengths")
|
||||
public void testContentLength(long expected, List<Long> lengths) {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testContentLength expected=%s %s%n%n", now(), expected, lengths);
|
||||
BodyPublisher[] publishers = ContentLengthPublisher.of(lengths);
|
||||
BodyPublisher aggregate = BodyPublishers.concat(publishers);
|
||||
assertEquals(aggregate.contentLength(), expected,
|
||||
assertEquals(expected, aggregate.contentLength(),
|
||||
"Unexpected result for %s".formatted(lengths));
|
||||
}
|
||||
|
||||
@ -692,14 +690,13 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
// publishers are no longer subscribed etc...
|
||||
@Test
|
||||
public void testCancel() {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testCancel%n%n", now());
|
||||
BodyPublisher[] publishers = BODIES.stream()
|
||||
.map(BodyPublishers::ofString)
|
||||
.toArray(BodyPublisher[]::new);
|
||||
BodyPublisher publisher = BodyPublishers.concat(publishers);
|
||||
|
||||
assertEquals(publisher.contentLength(),
|
||||
BODIES.stream().mapToInt(String::length).sum());
|
||||
assertEquals(BODIES.stream().mapToInt(String::length).sum(), publisher.contentLength());
|
||||
Map<RequestSubscriber, String> subscribers = new LinkedHashMap<>();
|
||||
|
||||
for (int n=0; n < BODIES.size(); n++) {
|
||||
@ -731,7 +728,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
|
||||
// subscription was cancelled, so nothing should be received...
|
||||
try {
|
||||
TimeoutException x = Assert.expectThrows(TimeoutException.class,
|
||||
TimeoutException x = Assertions.assertThrows(TimeoutException.class,
|
||||
() -> any.get(5, TimeUnit.SECONDS));
|
||||
out.println("Got expected " + x);
|
||||
} finally {
|
||||
@ -742,8 +739,8 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
subscribers.get(rs), rs.resultCF));
|
||||
}
|
||||
Consumer<RequestSubscriber> check = (rs) -> {
|
||||
Assert.assertTrue(rs.items.isEmpty(), subscribers.get(rs) + " has items");
|
||||
Assert.assertFalse(rs.resultCF.isDone(), subscribers.get(rs) + " was not cancelled");
|
||||
assertTrue(rs.items.isEmpty(), subscribers.get(rs) + " has items");
|
||||
assertFalse(rs.resultCF.isDone(), subscribers.get(rs) + " was not cancelled");
|
||||
out.println(subscribers.get(rs) + ": PASSED");
|
||||
};
|
||||
subscribers.keySet().stream().forEach(check);
|
||||
@ -752,13 +749,12 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
// Verifies that cancelling the subscription is propagated downstream
|
||||
@Test
|
||||
public void testCancelSubscription() {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- testCancelSubscription%n%n", now());
|
||||
PublishWithError upstream = new PublishWithError(BODIES, BODIES.size(),
|
||||
() -> new AssertionError("should not come here"));
|
||||
BodyPublisher publisher = BodyPublishers.concat(upstream);
|
||||
|
||||
assertEquals(publisher.contentLength(),
|
||||
BODIES.stream().mapToInt(String::length).sum());
|
||||
assertEquals(BODIES.stream().mapToInt(String::length).sum(), publisher.contentLength());
|
||||
Map<RequestSubscriber, String> subscribers = new LinkedHashMap<>();
|
||||
|
||||
for (int n=0; n < BODIES.size(); n++) {
|
||||
@ -793,7 +789,7 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
|
||||
// subscription was cancelled, so nothing should be received...
|
||||
try {
|
||||
TimeoutException x = Assert.expectThrows(TimeoutException.class,
|
||||
TimeoutException x = Assertions.assertThrows(TimeoutException.class,
|
||||
() -> any.get(5, TimeUnit.SECONDS));
|
||||
out.println("Got expected " + x);
|
||||
} finally {
|
||||
@ -804,17 +800,19 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
subscribers.get(rs), rs.resultCF));
|
||||
}
|
||||
Consumer<RequestSubscriber> check = (rs) -> {
|
||||
Assert.assertTrue(rs.items.isEmpty(), subscribers.get(rs) + " has items");
|
||||
Assert.assertFalse(rs.resultCF.isDone(), subscribers.get(rs) + " was not cancelled");
|
||||
assertTrue(rs.items.isEmpty(), subscribers.get(rs) + " has items");
|
||||
assertFalse(rs.resultCF.isDone(), subscribers.get(rs) + " was not cancelled");
|
||||
out.println(subscribers.get(rs) + ": PASSED");
|
||||
};
|
||||
subscribers.keySet().stream().forEach(check);
|
||||
|
||||
}
|
||||
|
||||
@Test(dataProvider = "variants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
public void test(URI uri, HttpClient.Version version, boolean sameClient) throws Exception {
|
||||
checkSkip();
|
||||
out.printf("%n%s-- test sameClient=%s, version=%s, uri=%s%n%n",
|
||||
now(), sameClient, version, uri);
|
||||
System.out.printf("Request to %s (sameClient: %s)%n", uri, sameClient);
|
||||
System.err.printf("Request to %s (sameClient: %s)%n", uri, sameClient);
|
||||
|
||||
@ -838,13 +836,13 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
int expectedResponse = RESPONSE_CODE;
|
||||
if (response.statusCode() != expectedResponse)
|
||||
throw new RuntimeException("wrong response code " + Integer.toString(response.statusCode()));
|
||||
assertEquals(response.body(), BODIES.stream().collect(Collectors.joining()));
|
||||
assertEquals(BODIES.stream().collect(Collectors.joining()), response.body());
|
||||
}
|
||||
if (!sameClient) client.close();
|
||||
System.out.println("test: DONE");
|
||||
}
|
||||
|
||||
private URI buildURI(String scheme, String path, int port) {
|
||||
private static URI buildURI(String scheme, String path, int port) {
|
||||
return URIBuilder.newBuilder()
|
||||
.scheme(scheme)
|
||||
.loopback()
|
||||
@ -853,8 +851,8 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
.buildUnchecked();
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
HttpTestHandler handler = new HttpTestEchoHandler();
|
||||
http1TestServer = HttpTestServer.create(HTTP_1_1);
|
||||
http1TestServer.addHandler(handler, "/http1/echo/");
|
||||
@ -884,8 +882,8 @@ public class AggregateRequestBodyTest implements HttpServerAdapters {
|
||||
http3TestServer.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
String sharedClientName =
|
||||
sharedClient == null ? null : sharedClient.toString();
|
||||
sharedClient.close();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @build jdk.test.lib.net.SimpleSSLContext
|
||||
* jdk.httpclient.test.lib.common.HttpServerAdapters
|
||||
* ReferenceTracker
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true
|
||||
* -Djdk.httpclient.HttpClient.log=requests,responses,errors
|
||||
* BasicHTTP2Test
|
||||
* @summary Basic HTTP/2 test when HTTP/3 is requested
|
||||
@ -44,37 +44,40 @@ import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpRequest.Builder;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static java.lang.System.out;
|
||||
import static java.net.http.HttpClient.Version.HTTP_2;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
|
||||
public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
String https2URI;
|
||||
DatagramSocket udp;
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static String https2URI;
|
||||
private static DatagramSocket udp;
|
||||
|
||||
// a shared executor helps reduce the amount of threads created by the test
|
||||
static final Executor executor = new TestExecutor(Executors.newCachedThreadPool());
|
||||
@ -91,8 +94,7 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -118,20 +120,37 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
var x = new SkipException("Skipping: some test failed");
|
||||
x.setStackTrace(new StackTraceElement[0]);
|
||||
throw x;
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static final void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
@ -152,14 +171,6 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] uris() {
|
||||
return new String[] {
|
||||
https2URI,
|
||||
};
|
||||
}
|
||||
|
||||
static AtomicLong URICOUNT = new AtomicLong();
|
||||
|
||||
private HttpClient makeNewClient() {
|
||||
clientCount.incrementAndGet();
|
||||
HttpClient client = HttpClient.newBuilder()
|
||||
@ -170,37 +181,6 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
return TRACKER.track(client);
|
||||
}
|
||||
|
||||
HttpClient newHttpClient(boolean share) {
|
||||
if (!share) return makeNewClient();
|
||||
HttpClient shared = sharedClient;
|
||||
if (shared != null) return shared;
|
||||
synchronized (this) {
|
||||
shared = sharedClient;
|
||||
if (shared == null) {
|
||||
shared = sharedClient = makeNewClient();
|
||||
}
|
||||
return shared;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void checkStatus(int expected, int found) throws Exception {
|
||||
if (expected != found) {
|
||||
System.err.printf ("Test failed: wrong status code %d/%d\n",
|
||||
expected, found);
|
||||
throw new RuntimeException("Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkStrings(String expected, String found) throws Exception {
|
||||
if (!expected.equals(found)) {
|
||||
System.err.printf ("Test failed: wrong string %s/%s\n",
|
||||
expected, found);
|
||||
throw new RuntimeException("Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testH2() throws Exception {
|
||||
|
||||
@ -220,8 +200,8 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
|
||||
out.println("Response #1: " + response);
|
||||
out.println("Version #1: " + response.version());
|
||||
assertEquals(response.statusCode(), 200, "first response status");
|
||||
assertEquals(response.version(), HTTP_2, "first response version");
|
||||
assertEquals(200, response.statusCode(), "first response status");
|
||||
assertEquals(HTTP_2, response.version(), "first response version");
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
@ -232,16 +212,15 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
response = client.send(request, BodyHandlers.ofString());
|
||||
out.println("Response #2: " + response);
|
||||
out.println("Version #2: " + response.version());
|
||||
assertEquals(response.statusCode(), 200, "second response status");
|
||||
assertEquals(response.version(), HTTP_2, "second response version");
|
||||
assertEquals(200, response.statusCode(), "second response status");
|
||||
assertEquals(HTTP_2, response.version(), "second response version");
|
||||
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
// HTTP/2
|
||||
HttpTestHandler handler = new Handler();
|
||||
HttpTestHandler h3Handler = new Handler();
|
||||
|
||||
https2TestServer = HttpTestServer.create(HTTP_2, sslContext);
|
||||
https2TestServer.addHandler(handler, "/https2/test204/");
|
||||
@ -259,11 +238,8 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
https2TestServer.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
String sharedClientName =
|
||||
sharedClient == null ? null : sharedClient.toString();
|
||||
sharedClient = null;
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
Thread.sleep(100);
|
||||
AssertionError fail = TRACKER.check(500);
|
||||
try {
|
||||
@ -271,10 +247,7 @@ public class BasicHTTP2Test implements HttpServerAdapters {
|
||||
https2TestServer.stop();
|
||||
} finally {
|
||||
if (fail != null) {
|
||||
if (sharedClientName != null) {
|
||||
System.err.println("Shared client name is: " + sharedClientName);
|
||||
}
|
||||
throw fail;
|
||||
throw fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,7 +31,6 @@ import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpRequest.Builder;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@ -40,28 +39,32 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
import jdk.httpclient.test.lib.http2.Http2TestServer;
|
||||
import jdk.internal.net.quic.QuicVersion;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static java.net.http.HttpClient.Version.HTTP_2;
|
||||
import static java.net.http.HttpClient.Version.HTTP_3;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import static java.lang.System.out;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@ -70,7 +73,7 @@ import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC;
|
||||
* jdk.httpclient.test.lib.common.HttpServerAdapters
|
||||
* ReferenceTracker
|
||||
* jdk.httpclient.test.lib.quic.QuicStandaloneServer
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true
|
||||
* -Djdk.httpclient.HttpClient.log=requests,responses,errors
|
||||
* -Djavax.net.debug=all
|
||||
* BasicHTTP3Test
|
||||
@ -79,20 +82,20 @@ import static java.net.http.HttpOption.Http3DiscoveryMode.ALT_SVC;
|
||||
public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
String https2URI;
|
||||
HttpTestServer h3TestServer; // HTTP/2 ( h2 + h3)
|
||||
String h3URI;
|
||||
HttpTestServer h3qv2TestServer; // HTTP/2 ( h2 + h3 on Quic v2, incompatible nego)
|
||||
String h3URIQv2;
|
||||
HttpTestServer h3qv2CTestServer; // HTTP/2 ( h2 + h3 on Quic v2, compatible nego)
|
||||
String h3URIQv2C;
|
||||
HttpTestServer h3mtlsTestServer; // HTTP/2 ( h2 + h3), h3 requires client cert
|
||||
String h3mtlsURI;
|
||||
HttpTestServer h3TestServerWithRetry; // h3
|
||||
String h3URIRetry;
|
||||
HttpTestServer h3TestServerWithTLSHelloRetry; // h3
|
||||
String h3URITLSHelloRetry;
|
||||
static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
static String https2URI;
|
||||
static HttpTestServer h3TestServer; // HTTP/2 ( h2 + h3)
|
||||
static String h3URI;
|
||||
static HttpTestServer h3qv2TestServer; // HTTP/2 ( h2 + h3 on Quic v2, incompatible nego)
|
||||
static String h3URIQv2;
|
||||
static HttpTestServer h3qv2CTestServer; // HTTP/2 ( h2 + h3 on Quic v2, compatible nego)
|
||||
static String h3URIQv2C;
|
||||
static HttpTestServer h3mtlsTestServer; // HTTP/2 ( h2 + h3), h3 requires client cert
|
||||
static String h3mtlsURI;
|
||||
static HttpTestServer h3TestServerWithRetry; // h3
|
||||
static String h3URIRetry;
|
||||
static HttpTestServer h3TestServerWithTLSHelloRetry; // h3
|
||||
static String h3URITLSHelloRetry;
|
||||
|
||||
static final int ITERATION_COUNT = 4;
|
||||
// a shared executor helps reduce the amount of threads created by the test
|
||||
@ -109,8 +112,8 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static volatile HttpClient sharedClient;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -136,21 +139,38 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
var x = new SkipException("Skipping: some test failed");
|
||||
x.setStackTrace(new StackTraceElement[0]);
|
||||
throw x;
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests() {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
out.printf("%n%sCreated %d clients%n",
|
||||
@ -170,18 +190,14 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] uris() {
|
||||
private static String[] uris() {
|
||||
return new String[] {
|
||||
https2URI,
|
||||
h3URI
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "variants")
|
||||
public Object[][] variants(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
return new Object[0][];
|
||||
}
|
||||
public static Object[][] variants() {
|
||||
String[] uris = uris();
|
||||
Object[][] result = new Object[uris.length * 2 * 2][];
|
||||
int i = 0;
|
||||
@ -196,11 +212,7 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
return result;
|
||||
}
|
||||
|
||||
@DataProvider(name = "h3URIs")
|
||||
public Object[][] versions(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
return new Object[0][];
|
||||
}
|
||||
public static Object[][] versions() {
|
||||
Object[][] result = {
|
||||
{h3URI}, {h3URIRetry},
|
||||
{h3URIQv2}, {h3URIQv2C},
|
||||
@ -233,9 +245,11 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "variants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
public void test(String uri, boolean sameClient, Optional<Version> version) throws Exception {
|
||||
System.out.println("Request to " + uri);
|
||||
System.out.printf("%n%s-- test version=%s, sameClient=%s, uri=%s%n%n",
|
||||
now(), version, sameClient, uri);
|
||||
|
||||
HttpClient client = newHttpClient(sameClient);
|
||||
|
||||
@ -267,8 +281,10 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
System.out.println("test: DONE");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "h3URIs")
|
||||
@ParameterizedTest
|
||||
@MethodSource("versions")
|
||||
public void testH3(final String h3URI) throws Exception {
|
||||
System.out.printf("%n%s-- testH3 h3URI=%s%n%n", now(), h3URI);
|
||||
HttpClient client = makeNewClient();
|
||||
URI uri = URI.create(h3URI);
|
||||
Builder builder = HttpRequest.newBuilder(uri)
|
||||
@ -278,17 +294,17 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
|
||||
out.println("Response #1: " + response);
|
||||
out.println("Version #1: " + response.version());
|
||||
assertEquals(response.statusCode(), 200, "first response status");
|
||||
assertEquals(response.version(), HTTP_2, "first response version");
|
||||
assertEquals(200, response.statusCode(), "first response status");
|
||||
assertEquals(HTTP_2, response.version(), "first response version");
|
||||
|
||||
request = builder.version(Version.HTTP_3).build();
|
||||
response = client.send(request, BodyHandlers.ofString());
|
||||
out.println("Response #2: " + response);
|
||||
out.println("Version #2: " + response.version());
|
||||
assertEquals(response.statusCode(), 200, "second response status");
|
||||
assertEquals(response.version(), Version.HTTP_3, "second response version");
|
||||
assertEquals(200, response.statusCode(), "second response status");
|
||||
assertEquals(Version.HTTP_3, response.version(), "second response version");
|
||||
|
||||
if (h3URI == h3mtlsURI) {
|
||||
if (h3URI.equals(h3mtlsURI)) {
|
||||
assertNotNull(response.sslSession().get().getLocalCertificates());
|
||||
} else {
|
||||
assertNull(response.sslSession().get().getLocalCertificates());
|
||||
@ -303,6 +319,7 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
// verify that the client handles HTTP/3 reset stream correctly
|
||||
@Test
|
||||
public void testH3Reset() throws Exception {
|
||||
System.out.printf("%n%s-- testH3Reset uri=%s%n%n", now(), h3URI);
|
||||
HttpClient client = makeNewClient();
|
||||
URI uri = URI.create(h3URI);
|
||||
Builder builder = HttpRequest.newBuilder(uri)
|
||||
@ -312,8 +329,8 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
|
||||
out.println("Response #1: " + response);
|
||||
out.println("Version #1: " + response.version());
|
||||
assertEquals(response.statusCode(), 200, "first response status");
|
||||
assertEquals(response.version(), HTTP_2, "first response version");
|
||||
assertEquals(200, response.statusCode(), "first response status");
|
||||
assertEquals(HTTP_2, response.version(), "first response version");
|
||||
|
||||
// instruct the server side handler to throw an exception
|
||||
// that then causes the test server to reset the stream
|
||||
@ -341,8 +358,8 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
if (error != null) throw error;
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
https2TestServer = HttpTestServer.create(HTTP_2, sslContext);
|
||||
https2TestServer.addHandler(new Handler(), "/https2/test/");
|
||||
https2URI = "https://" + https2TestServer.serverAuthority() + "/https2/test/x";
|
||||
@ -360,7 +377,7 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
.enableH3AltServiceOnEphemeralPortWithVersion(QuicVersion.QUIC_V2, false);
|
||||
h3qv2TestServer = HttpTestServer.of(h2q2Server);
|
||||
h3qv2TestServer.addHandler(h3Handler, "/h3/testH3/");
|
||||
h3URIQv2 = "https://" + h3qv2TestServer.serverAuthority() + "/h3/testH3/h3qv2";;
|
||||
h3URIQv2 = "https://" + h3qv2TestServer.serverAuthority() + "/h3/testH3/h3qv2";
|
||||
assertTrue(h3qv2TestServer.canHandle(HTTP_2, Version.HTTP_3), "Server was expected" +
|
||||
" to handle both HTTP2 and HTTP3, but doesn't");
|
||||
|
||||
@ -369,7 +386,7 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
.enableH3AltServiceOnEphemeralPortWithVersion(QuicVersion.QUIC_V2, true);
|
||||
h3qv2CTestServer = HttpTestServer.of(h2q2CServer);
|
||||
h3qv2CTestServer.addHandler(h3Handler, "/h3/testH3/");
|
||||
h3URIQv2C = "https://" + h3qv2CTestServer.serverAuthority() + "/h3/testH3/h3qv2c";;
|
||||
h3URIQv2C = "https://" + h3qv2CTestServer.serverAuthority() + "/h3/testH3/h3qv2c";
|
||||
assertTrue(h3qv2CTestServer.canHandle(HTTP_2, Version.HTTP_3), "Server was expected" +
|
||||
" to handle both HTTP2 and HTTP3, but doesn't");
|
||||
|
||||
@ -411,8 +428,8 @@ public class BasicHTTP3Test implements HttpServerAdapters {
|
||||
h3TestServerWithTLSHelloRetry.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
System.err.println("=======================================================");
|
||||
System.err.println(" Tearing down test");
|
||||
System.err.println("=======================================================");
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
* @key randomness
|
||||
* @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext
|
||||
* ReferenceTracker CancelRequestTest
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true
|
||||
* -Djdk.httpclient.enableAllMethodRetry=true
|
||||
* CancelRequestTest
|
||||
*/
|
||||
@ -38,15 +38,6 @@
|
||||
import jdk.internal.net.http.common.OperationTrackers.Tracker;
|
||||
import jdk.test.lib.RandomFactory;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
@ -61,7 +52,6 @@ import java.net.http.HttpOption.Http3DiscoveryMode;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandler;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -76,7 +66,6 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
|
||||
import static java.lang.System.out;
|
||||
@ -85,10 +74,21 @@ import static java.net.http.HttpClient.Version.*;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class CancelRequestTest implements HttpServerAdapters {
|
||||
|
||||
@ -97,19 +97,19 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
HttpTestServer h2h3TestServer; // HTTP/3 ( h2 + h3 )
|
||||
HttpTestServer h3TestServer; // HTTP/3 ( h3 )
|
||||
String httpURI;
|
||||
String httpsURI;
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
String h2h3URI;
|
||||
String h2h3Head;
|
||||
String h3URI;
|
||||
private static HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
private static HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer h2h3TestServer; // HTTP/3 ( h2 + h3 )
|
||||
private static HttpTestServer h3TestServer; // HTTP/3 ( h3 )
|
||||
private static String httpURI;
|
||||
private static String httpsURI;
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static String h2h3URI;
|
||||
private static String h2h3Head;
|
||||
private static String h3URI;
|
||||
|
||||
static final long SERVER_LATENCY = 75;
|
||||
static final int MAX_CLIENT_DELAY = 75;
|
||||
@ -130,8 +130,8 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static volatile HttpClient sharedClient;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -157,38 +157,39 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static void printFailedTests(ITestContext context) {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
var failed = context.getFailedTests().getAllResults().stream()
|
||||
.collect(Collectors.toMap(CancelRequestTest::name, ITestResult::getThrowable));
|
||||
FAILURES.putAll(failed);
|
||||
try {
|
||||
out.printf("%n%sCreated %d servers and %d clients%n",
|
||||
now(), serverCount.get(), clientCount.get());
|
||||
@ -206,7 +207,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] uris() {
|
||||
private static String[] uris() {
|
||||
return new String[] {
|
||||
httpURI,
|
||||
httpsURI,
|
||||
@ -217,8 +218,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "asyncurls")
|
||||
public Object[][] asyncurls() {
|
||||
public static Object[][] asyncurls() {
|
||||
String[] uris = uris();
|
||||
Object[][] result = new Object[uris.length * 2 * 3][];
|
||||
//Object[][] result = new Object[uris.length][];
|
||||
@ -238,8 +238,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
return result;
|
||||
}
|
||||
|
||||
@DataProvider(name = "urls")
|
||||
public Object[][] alltests() {
|
||||
public static Object[][] alltests() {
|
||||
String[] uris = uris();
|
||||
Object[][] result = new Object[uris.length * 2][];
|
||||
//Object[][] result = new Object[uris.length][];
|
||||
@ -327,7 +326,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
.HEAD()
|
||||
.build();
|
||||
var resp = client.send(request, BodyHandlers.discarding());
|
||||
assertEquals(resp.statusCode(), 200);
|
||||
assertEquals(200, resp.statusCode());
|
||||
}
|
||||
|
||||
private static void releaseLatches() {
|
||||
@ -348,10 +347,10 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
return latch;
|
||||
}
|
||||
|
||||
@Test(dataProvider = "asyncurls")
|
||||
@ParameterizedTest
|
||||
@MethodSource("asyncurls")
|
||||
public void testGetSendAsync(String uri, boolean sameClient, boolean mayInterruptIfRunning)
|
||||
throws Exception {
|
||||
checkSkip();
|
||||
HttpClient client = null;
|
||||
uri = uri + "/get";
|
||||
out.printf("%n%s testGetSendAsync(%s, %b, %b)%n", now(), uri, sameClient, mayInterruptIfRunning);
|
||||
@ -386,7 +385,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
out.println("cf2 after cancel: " + cf2);
|
||||
try {
|
||||
String body = cf2.get().body();
|
||||
assertEquals(body, String.join("", BODY.split("\\|")));
|
||||
assertEquals(String.join("", BODY.split("\\|")), body);
|
||||
throw new AssertionError("Expected CancellationException not received");
|
||||
} catch (ExecutionException x) {
|
||||
out.println(now() + "Got expected exception: " + x);
|
||||
@ -409,7 +408,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
// completed yet - so wait for it here...
|
||||
try {
|
||||
String body = response.get().body();
|
||||
assertEquals(body, String.join("", BODY.split("\\|")));
|
||||
assertEquals(String.join("", BODY.split("\\|")), body);
|
||||
if (mayInterruptIfRunning) {
|
||||
// well actually - this could happen... In which case we'll need to
|
||||
// increase the latency in the server handler...
|
||||
@ -448,10 +447,10 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
|
||||
assertTrue(response.isDone());
|
||||
assertFalse(response.isCancelled());
|
||||
assertEquals(cf1.isCancelled(), hasCancellationException);
|
||||
assertEquals(hasCancellationException, cf1.isCancelled());
|
||||
assertTrue(cf2.isDone());
|
||||
assertFalse(cf2.isCancelled());
|
||||
assertEquals(latch.getCount(), 0);
|
||||
assertEquals(0, latch.getCount());
|
||||
|
||||
var error = TRACKER.check(tracker, 1000,
|
||||
(t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0,
|
||||
@ -464,10 +463,10 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
if (!sameClient) client.close();
|
||||
}
|
||||
|
||||
@Test(dataProvider = "asyncurls")
|
||||
@ParameterizedTest
|
||||
@MethodSource("asyncurls")
|
||||
public void testPostSendAsync(String uri, boolean sameClient, boolean mayInterruptIfRunning)
|
||||
throws Exception {
|
||||
checkSkip();
|
||||
uri = uri + "/post";
|
||||
HttpClient client = null;
|
||||
out.printf("%n%s testPostSendAsync(%s, %b, %b)%n", now(), uri, sameClient, mayInterruptIfRunning);
|
||||
@ -521,7 +520,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
out.println("cf2 after cancel: " + cf2);
|
||||
try {
|
||||
String body = cf2.get().body();
|
||||
assertEquals(body, String.join("", BODY.split("\\|")));
|
||||
assertEquals(String.join("", BODY.split("\\|")), body);
|
||||
throw new AssertionError("Expected CancellationException not received");
|
||||
} catch (ExecutionException x) {
|
||||
out.println(now() + "Got expected exception: " + x);
|
||||
@ -544,7 +543,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
// completed yet - so wait for it here...
|
||||
try {
|
||||
String body = response.get().body();
|
||||
assertEquals(body, String.join("", BODY.split("\\|")));
|
||||
assertEquals(String.join("", BODY.split("\\|")), body);
|
||||
if (mayInterruptIfRunning) {
|
||||
// well actually - this could happen... In which case we'll need to
|
||||
// increase the latency in the server handler...
|
||||
@ -577,10 +576,10 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
|
||||
assertTrue(response.isDone());
|
||||
assertFalse(response.isCancelled());
|
||||
assertEquals(cf1.isCancelled(), hasCancellationException);
|
||||
assertEquals(hasCancellationException, cf1.isCancelled());
|
||||
assertTrue(cf2.isDone());
|
||||
assertFalse(cf2.isCancelled());
|
||||
assertEquals(latch.getCount(), 0);
|
||||
assertEquals(0, latch.getCount());
|
||||
|
||||
var error = TRACKER.check(tracker, 1000,
|
||||
(t) -> t.getOutstandingOperations() > 0 || t.getOutstandingSubscribers() > 0,
|
||||
@ -593,10 +592,10 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
if (!sameClient) client.close();
|
||||
}
|
||||
|
||||
@Test(dataProvider = "urls")
|
||||
@ParameterizedTest
|
||||
@MethodSource("alltests")
|
||||
public void testPostInterrupt(String uri, boolean sameClient)
|
||||
throws Exception {
|
||||
checkSkip();
|
||||
HttpClient client = null;
|
||||
out.printf("%n%s testPostInterrupt(%s, %b)%n", now(), uri, sameClient);
|
||||
for (int i=0; i< ITERATION_COUNT; i++) {
|
||||
@ -661,7 +660,7 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
} else {
|
||||
assert failed == null;
|
||||
out.println(now() + req.uri() + ": got body: " + body);
|
||||
assertEquals(body, String.join("", BODY.split("\\|")));
|
||||
assertEquals(String.join("", BODY.split("\\|")), body);
|
||||
}
|
||||
out.println(now() + "next iteration");
|
||||
|
||||
@ -678,8 +677,8 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
|
||||
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
// HTTP/1.1
|
||||
HttpTestHandler h1_chunkHandler = new HTTPSlowHandler();
|
||||
httpTestServer = HttpTestServer.create(HTTP_1_1);
|
||||
@ -721,8 +720,8 @@ public class CancelRequestTest implements HttpServerAdapters {
|
||||
h3TestServer.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
String sharedClientName =
|
||||
sharedClient == null ? null : sharedClient.toString();
|
||||
sharedClient = null;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,19 +29,10 @@
|
||||
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
||||
* @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext
|
||||
* ReferenceTracker CancelStreamedBodyTest
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true
|
||||
* CancelStreamedBodyTest
|
||||
*/
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
@ -53,7 +44,6 @@ import java.net.http.HttpClient;
|
||||
import java.net.http.HttpClient.Version;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
@ -61,7 +51,6 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
|
||||
@ -72,23 +61,34 @@ import static java.net.http.HttpClient.Version.HTTP_3;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
String httpURI;
|
||||
String httpsURI;
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
String https3URI;
|
||||
private static HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
private static HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
private static String httpURI;
|
||||
private static String httpsURI;
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static String https3URI;
|
||||
|
||||
static final long SERVER_LATENCY = 75;
|
||||
static final int ITERATION_COUNT = 3;
|
||||
@ -108,8 +108,8 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static volatile HttpClient sharedClient;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -135,38 +135,40 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests(ITestContext context) {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
var failed = context.getFailedTests().getAllResults().stream()
|
||||
.collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable));
|
||||
FAILURES.putAll(failed);
|
||||
try {
|
||||
out.printf("%n%sCreated %d servers and %d clients%n",
|
||||
now(), serverCount.get(), clientCount.get());
|
||||
@ -184,7 +186,7 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] uris() {
|
||||
private static String[] uris() {
|
||||
return new String[] {
|
||||
https3URI,
|
||||
httpURI,
|
||||
@ -195,8 +197,7 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
}
|
||||
|
||||
|
||||
@DataProvider(name = "urls")
|
||||
public Object[][] alltests() {
|
||||
public static Object[][] alltests() {
|
||||
String[] uris = uris();
|
||||
Object[][] result = new Object[uris.length * 2][];
|
||||
int i = 0;
|
||||
@ -265,10 +266,10 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
|
||||
final static String BODY = "Some string |\n that ?\n can |\n be split ?\n several |\n ways.";
|
||||
|
||||
@Test(dataProvider = "urls")
|
||||
@ParameterizedTest
|
||||
@MethodSource("alltests")
|
||||
public void testAsLines(String uri, boolean sameClient)
|
||||
throws Exception {
|
||||
checkSkip();
|
||||
HttpClient client = null;
|
||||
uri = uri + "/testAsLines";
|
||||
out.printf("%n%s testAsLines(%s, %b)%n", now(), uri, sameClient);
|
||||
@ -284,8 +285,8 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
try (Stream<String> body = client.send(req, BodyHandlers.ofLines()).body()) {
|
||||
lines = body.limit(j).toList();
|
||||
assertEquals(lines, BODY.replaceAll("\\||\\?", "")
|
||||
.lines().limit(j).toList());
|
||||
assertEquals(BODY.replaceAll("\\||\\?", "")
|
||||
.lines().limit(j).toList(), lines);
|
||||
}
|
||||
// Only check our still alive client for outstanding operations
|
||||
// and outstanding subscribers here: it should have none.
|
||||
@ -306,10 +307,10 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "urls")
|
||||
@ParameterizedTest
|
||||
@MethodSource("alltests")
|
||||
public void testInputStream(String uri, boolean sameClient)
|
||||
throws Exception {
|
||||
checkSkip();
|
||||
HttpClient client = null;
|
||||
uri = uri + "/testInputStream";
|
||||
out.printf("%n%s testInputStream(%s, %b)%n", now(), uri, sameClient);
|
||||
@ -326,7 +327,7 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
try (InputStream is = client.send(req, BodyHandlers.ofInputStream()).body()) {
|
||||
for (int k = 0; k < j; k++) {
|
||||
read = is.read();
|
||||
assertEquals(read, BODY.charAt(k));
|
||||
assertEquals(BODY.charAt(k), read);
|
||||
}
|
||||
}
|
||||
// Only check our still alive client for outstanding operations
|
||||
@ -350,8 +351,8 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
|
||||
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
// HTTP/1.1
|
||||
HttpTestHandler h1_chunkHandler = new HTTPSlowHandler();
|
||||
httpTestServer = HttpTestServer.create(HTTP_1_1);
|
||||
@ -385,8 +386,8 @@ public class CancelStreamedBodyTest implements HttpServerAdapters {
|
||||
http3TestServer.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
String sharedClientName =
|
||||
sharedClient == null ? null : sharedClient.toString();
|
||||
sharedClient = null;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,7 +28,7 @@
|
||||
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
||||
* @build DigestEchoServer ForbiddenHeadTest jdk.httpclient.test.lib.common.HttpServerAdapters
|
||||
* jdk.test.lib.net.SimpleSSLContext
|
||||
* @run testng/othervm
|
||||
* @run junit/othervm
|
||||
* -Djdk.http.auth.tunneling.disabledSchemes
|
||||
* -Djdk.httpclient.HttpClient.log=headers,requests
|
||||
* -Djdk.internal.httpclient.debug=true
|
||||
@ -36,15 +36,6 @@
|
||||
*/
|
||||
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
@ -61,7 +52,6 @@ import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -81,27 +71,40 @@ import static java.net.http.HttpClient.Version.HTTP_3;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
|
||||
import static jdk.httpclient.test.lib.common.HttpServerAdapters.createClientBuilderForH3;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer httpTestServer; // HTTP/1.1
|
||||
HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
DigestEchoServer.TunnelingProxy proxy;
|
||||
DigestEchoServer.TunnelingProxy authproxy;
|
||||
String httpURI;
|
||||
String httpsURI;
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
String https3URI;
|
||||
HttpClient authClient;
|
||||
HttpClient noAuthClient;
|
||||
private static HttpTestServer httpTestServer; // HTTP/1.1
|
||||
private static HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
private static DigestEchoServer.TunnelingProxy proxy;
|
||||
private static DigestEchoServer.TunnelingProxy authproxy;
|
||||
private static String httpURI;
|
||||
private static String httpsURI;
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static String https3URI;
|
||||
private static HttpClient authClient;
|
||||
private static HttpClient noAuthClient;
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
static final long SLEEP_AFTER_TEST = 0; // milliseconds
|
||||
static final int ITERATIONS = 3;
|
||||
static final Executor executor = new TestExecutor(Executors.newCachedThreadPool());
|
||||
@ -142,34 +145,39 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests(ITestContext context) {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
// Exceptions should already have been added to FAILURES
|
||||
@ -201,8 +209,7 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
static final String MESSAGE = "Unauthorized";
|
||||
|
||||
|
||||
@DataProvider(name = "all")
|
||||
public Object[][] allcases() {
|
||||
public static Object[][] allcases() {
|
||||
List<Object[]> result = new ArrayList<>();
|
||||
for (boolean useAuth : List.of(true, false)) {
|
||||
for (boolean async : List.of(true, false)) {
|
||||
@ -226,8 +233,6 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
return result.toArray(new Object[0][0]);
|
||||
}
|
||||
|
||||
static final AtomicLong requestCounter = new AtomicLong();
|
||||
|
||||
static final Authenticator authenticator = new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
@ -237,9 +242,9 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
|
||||
static final AtomicLong sleepCount = new AtomicLong();
|
||||
|
||||
@Test(dataProvider = "all")
|
||||
@ParameterizedTest
|
||||
@MethodSource("allcases")
|
||||
void test(String uriString, int code, boolean async, boolean useAuth) throws Throwable {
|
||||
checkSkip();
|
||||
HttpClient client = useAuth ? authClient : noAuthClient;
|
||||
var name = String.format("test(%s, %d, %s, %s)", uriString, code, async ? "async" : "sync",
|
||||
client.authenticator().isPresent() ? "authClient" : "noAuthClient");
|
||||
@ -318,23 +323,23 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
|
||||
|
||||
out.println(" Got response: " + response);
|
||||
assertEquals(response.statusCode(), forbidden? FORBIDDEN : code);
|
||||
assertEquals(response.body(), expectedValue == null ? null : "");
|
||||
assertEquals(response.headers().firstValue("X-value"), Optional.ofNullable(expectedValue));
|
||||
assertEquals(forbidden? FORBIDDEN : code, response.statusCode());
|
||||
assertEquals(expectedValue == null ? null : "", response.body());
|
||||
assertEquals(Optional.ofNullable(expectedValue), response.headers().firstValue("X-value"));
|
||||
// when the CONNECT request fails, its body is discarded - but
|
||||
// the response header may still contain its content length.
|
||||
// don't check content length in that case.
|
||||
if (expectedValue != null) {
|
||||
String clen = String.valueOf(expectedValue.getBytes(UTF_8).length);
|
||||
assertEquals(response.headers().firstValue("Content-Length"), Optional.of(clen));
|
||||
assertEquals(Optional.of(clen), response.headers().firstValue("Content-Length"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -- Infrastructure
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
httpTestServer = HttpTestServer.create(HTTP_1_1);
|
||||
httpTestServer.addHandler(new UnauthorizedHandler(), "/http1/");
|
||||
httpTestServer.addHandler(new UnauthorizedHandler(), "/http2/proxy/");
|
||||
@ -357,7 +362,7 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
proxy = DigestEchoServer.createHttpsProxyTunnel(DigestEchoServer.HttpAuthSchemeType.NONE);
|
||||
authproxy = DigestEchoServer.createHttpsProxyTunnel(DigestEchoServer.HttpAuthSchemeType.BASIC);
|
||||
|
||||
authClient = TRACKER.track(newClientBuilderForH3()
|
||||
authClient = TRACKER.track(createClientBuilderForH3()
|
||||
.proxy(TestProxySelector.of(proxy, authproxy, httpTestServer))
|
||||
.sslContext(sslContext)
|
||||
.executor(executor)
|
||||
@ -365,7 +370,7 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
.build());
|
||||
clientCount.incrementAndGet();
|
||||
|
||||
noAuthClient = TRACKER.track(newClientBuilderForH3()
|
||||
noAuthClient = TRACKER.track(createClientBuilderForH3()
|
||||
.proxy(TestProxySelector.of(proxy, authproxy, httpTestServer))
|
||||
.sslContext(sslContext)
|
||||
.executor(executor)
|
||||
@ -384,8 +389,8 @@ public class ForbiddenHeadTest implements HttpServerAdapters {
|
||||
serverCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
authClient = noAuthClient = null;
|
||||
Thread.sleep(100);
|
||||
AssertionError fail = TRACKER.check(1500);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,7 +43,6 @@ import jdk.internal.net.http.common.Utils;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@ -63,19 +62,18 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
* jdk.httpclient.test.lib.common.HttpServerAdapters
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true HeadersLowerCaseTest
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class HeadersLowerCaseTest implements HttpServerAdapters {
|
||||
|
||||
private static Set<String> REQUEST_HEADERS;
|
||||
|
||||
private HttpTestServer h2server;
|
||||
private HttpTestServer h3server;
|
||||
private String h2ReqURIBase;
|
||||
private String h3ReqURIBase;
|
||||
private static HttpTestServer h2server;
|
||||
private static HttpTestServer h3server;
|
||||
private static String h2ReqURIBase;
|
||||
private static String h3ReqURIBase;
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
|
||||
@BeforeAll
|
||||
public void beforeAll() throws Exception {
|
||||
public static void beforeAll() throws Exception {
|
||||
h2server = HttpTestServer.create(HTTP_2, sslContext);
|
||||
h2server.start();
|
||||
h2ReqURIBase = "https://" + h2server.serverAuthority();
|
||||
@ -100,7 +98,7 @@ public class HeadersLowerCaseTest implements HttpServerAdapters {
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public void afterAll() throws Exception {
|
||||
public static void afterAll() throws Exception {
|
||||
if (h2server != null) {
|
||||
h2server.stop();
|
||||
}
|
||||
@ -157,14 +155,14 @@ public class HeadersLowerCaseTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<Arguments> params() throws Exception {
|
||||
private static Stream<Arguments> params() throws Exception {
|
||||
return Stream.of(
|
||||
Arguments.of(HTTP_2, new URI(h2ReqURIBase + "/h2verifyReqHeaders")),
|
||||
Arguments.of(Version.HTTP_3, new URI(h3ReqURIBase + "/h3verifyReqHeaders")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a HTTP/2 or HTTP/3 request with header names of varying case (some in lower,
|
||||
* Issues an HTTP/2 or HTTP/3 request with header names of varying case (some in lower,
|
||||
* some mixed, some upper case) and expects that the client internally converts them
|
||||
* to lower case before encoding and sending to the server. The server side handler verifies
|
||||
* that it receives the header names in lower case and if it doesn't then it returns a
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,7 +21,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
/*
|
||||
* @test
|
||||
* @bug 8306040
|
||||
* @summary HttpResponseInputStream.available() returns 1 on empty stream
|
||||
@ -47,19 +47,17 @@ import java.net.http.HttpResponse;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class HttpInputStreamAvailableTest {
|
||||
|
||||
private HttpServer server;
|
||||
private int port;
|
||||
static final String TEST_MESSAGE = "This is test message";
|
||||
static final int ZERO = 0;
|
||||
private static HttpServer server;
|
||||
private static int port;
|
||||
private static final String TEST_MESSAGE = "This is test message";
|
||||
private static final int ZERO = 0;
|
||||
|
||||
@BeforeAll
|
||||
void setup() throws Exception {
|
||||
static void setup() throws Exception {
|
||||
InetAddress loopback = InetAddress.getLoopbackAddress();
|
||||
InetSocketAddress addr = new InetSocketAddress(loopback, 0);
|
||||
server = HttpServer.create(addr, 0);
|
||||
@ -72,69 +70,71 @@ public class HttpInputStreamAvailableTest {
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
void teardown() throws Exception {
|
||||
static void teardown() throws Exception {
|
||||
server.stop(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
HttpClient client = HttpClient
|
||||
try (HttpClient client = HttpClient
|
||||
.newBuilder()
|
||||
.proxy(HttpClient.Builder.NO_PROXY)
|
||||
.build();
|
||||
.build()) {
|
||||
|
||||
URI uri = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(port)
|
||||
.path("/NonZeroResponse/")
|
||||
.build();
|
||||
URI uri = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(port)
|
||||
.path("/NonZeroResponse/")
|
||||
.build();
|
||||
|
||||
HttpRequest request = HttpRequest
|
||||
.newBuilder(uri)
|
||||
.GET()
|
||||
.build();
|
||||
HttpRequest request = HttpRequest
|
||||
.newBuilder(uri)
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
// Send a httpRequest and assert the bytes available
|
||||
HttpResponse<InputStream> response = client.send(request,
|
||||
HttpResponse.BodyHandlers.ofInputStream());
|
||||
try ( InputStream in = response.body()) {
|
||||
in.readNBytes(2);
|
||||
// this is not guaranteed, but a failure here would be surprising
|
||||
assertEquals(TEST_MESSAGE.length() - 2, in.available());
|
||||
//read the remaining data
|
||||
in.readAllBytes();
|
||||
//available should return 0
|
||||
assertEquals(ZERO, in.available());
|
||||
// Send a httpRequest and assert the bytes available
|
||||
HttpResponse<InputStream> response = client.send(request,
|
||||
HttpResponse.BodyHandlers.ofInputStream());
|
||||
try (InputStream in = response.body()) {
|
||||
in.readNBytes(2);
|
||||
// this is not guaranteed, but a failure here would be surprising
|
||||
assertEquals(TEST_MESSAGE.length() - 2, in.available());
|
||||
//read the remaining data
|
||||
in.readAllBytes();
|
||||
//available should return 0
|
||||
assertEquals(ZERO, in.available());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() throws Exception {
|
||||
HttpClient client = HttpClient
|
||||
try (HttpClient client = HttpClient
|
||||
.newBuilder()
|
||||
.proxy(HttpClient.Builder.NO_PROXY)
|
||||
.build();
|
||||
.build()) {
|
||||
|
||||
URI uri = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(port)
|
||||
.path("/ZeroResponse/")
|
||||
.build();
|
||||
URI uri = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(port)
|
||||
.path("/ZeroResponse/")
|
||||
.build();
|
||||
|
||||
HttpRequest request = HttpRequest
|
||||
.newBuilder(uri)
|
||||
.GET()
|
||||
.build();
|
||||
HttpRequest request = HttpRequest
|
||||
.newBuilder(uri)
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
// Send a httpRequest and assert the bytes available
|
||||
HttpResponse<InputStream> response = client.send(request,
|
||||
HttpResponse.BodyHandlers.ofInputStream());
|
||||
try ( InputStream in = response.body()) {
|
||||
assertEquals(ZERO, in.available());
|
||||
in.readAllBytes();
|
||||
assertEquals(ZERO, in.available());
|
||||
// Send a httpRequest and assert the bytes available
|
||||
HttpResponse<InputStream> response = client.send(request,
|
||||
HttpResponse.BodyHandlers.ofInputStream());
|
||||
try (InputStream in = response.body()) {
|
||||
assertEquals(ZERO, in.available());
|
||||
in.readAllBytes();
|
||||
assertEquals(ZERO, in.available());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,7 +35,6 @@ import jdk.test.lib.net.URIBuilder;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -53,18 +52,17 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class HttpResponseInputStreamInterruptTest {
|
||||
|
||||
HttpServer server;
|
||||
int port;
|
||||
private final CountDownLatch interruptReadyLatch = new CountDownLatch(2);
|
||||
private final CountDownLatch interruptDoneLatch = new CountDownLatch(1);
|
||||
private static HttpServer server;
|
||||
private static int port;
|
||||
private static final CountDownLatch interruptReadyLatch = new CountDownLatch(2);
|
||||
private static final CountDownLatch interruptDoneLatch = new CountDownLatch(1);
|
||||
static final String FIRST_MESSAGE = "Should be received";
|
||||
static final String SECOND_MESSAGE = "Shouldn't be received";
|
||||
|
||||
@BeforeAll
|
||||
void before() throws Exception {
|
||||
static void before() throws Exception {
|
||||
InetAddress loopback = InetAddress.getLoopbackAddress();
|
||||
InetSocketAddress addr = new InetSocketAddress(loopback, 0);
|
||||
server = HttpServer.create(addr, 0);
|
||||
@ -75,7 +73,7 @@ public class HttpResponseInputStreamInterruptTest {
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
void after() throws Exception {
|
||||
static void after() throws Exception {
|
||||
server.stop(0);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
||||
* @build jdk.httpclient.test.lib.common.HttpServerAdapters jdk.test.lib.net.SimpleSSLContext
|
||||
* ReferenceTracker
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true
|
||||
* -Djdk.httpclient.HttpClient.log=requests,responses,errors
|
||||
* ISO_8859_1_Test
|
||||
* @summary Tests that a client is able to receive ISO-8859-1 encoded header values.
|
||||
@ -48,7 +48,6 @@ import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
@ -60,21 +59,11 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static java.lang.System.out;
|
||||
import static java.net.http.HttpClient.Version.HTTP_1_1;
|
||||
@ -82,30 +71,38 @@ import static java.net.http.HttpClient.Version.HTTP_2;
|
||||
import static java.net.http.HttpClient.Version.HTTP_3;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
DummyServer http1DummyServer;
|
||||
HttpTestServer http1TestServer; // HTTP/1.1 ( http )
|
||||
HttpTestServer https1TestServer; // HTTPS/1.1 ( https )
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
String http1Dummy;
|
||||
String http1URI;
|
||||
String https1URI;
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
String http3URI;
|
||||
private static DummyServer http1DummyServer;
|
||||
private static HttpTestServer http1TestServer; // HTTP/1.1 ( http )
|
||||
private static HttpTestServer https1TestServer; // HTTPS/1.1 ( https )
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
private static String http1Dummy;
|
||||
private static String http1URI;
|
||||
private static String https1URI;
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static String http3URI;
|
||||
|
||||
static final int RESPONSE_CODE = 200;
|
||||
static final int ITERATION_COUNT = 4;
|
||||
static final Class<IllegalArgumentException> IAE = IllegalArgumentException.class;
|
||||
static final Class<CompletionException> CE = CompletionException.class;
|
||||
// a shared executor helps reduce the amount of threads created by the test
|
||||
static final Executor executor = new TestExecutor(Executors.newCachedThreadPool());
|
||||
static final ConcurrentMap<String, Throwable> FAILURES = new ConcurrentHashMap<>();
|
||||
@ -121,8 +118,8 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static volatile HttpClient sharedClient;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -148,40 +145,40 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests(ITestContext context) {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
var failed = context.getFailedTests().getAllResults().stream()
|
||||
.collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable));
|
||||
FAILURES.putAll(failed);
|
||||
|
||||
out.printf("%n%sCreated %d servers and %d clients%n",
|
||||
now(), serverCount.get(), clientCount.get());
|
||||
if (FAILURES.isEmpty()) return;
|
||||
@ -199,7 +196,7 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] uris() {
|
||||
private static String[] uris() {
|
||||
return new String[] {
|
||||
http3URI,
|
||||
http1Dummy,
|
||||
@ -210,13 +207,7 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
};
|
||||
}
|
||||
|
||||
static AtomicLong URICOUNT = new AtomicLong();
|
||||
|
||||
@DataProvider(name = "variants")
|
||||
public Object[][] variants(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
return new Object[0][];
|
||||
}
|
||||
public static Object[][] variants() {
|
||||
String[] uris = uris();
|
||||
Object[][] result = new Object[uris.length * 2][];
|
||||
int i = 0;
|
||||
@ -265,7 +256,7 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Exception completionCause(CompletionException x) {
|
||||
private static Exception completionCause(CompletionException x) {
|
||||
Throwable c = x;
|
||||
while (c instanceof CompletionException
|
||||
|| c instanceof ExecutionException) {
|
||||
@ -285,10 +276,11 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Test(dataProvider = "variants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
public void test(String uri, boolean sameClient) throws Exception {
|
||||
checkSkip();
|
||||
System.out.println("Request to " + uri);
|
||||
|
||||
System.out.printf("%n%s-- test sameClient=%s uri=%s%n%n", now(), sameClient, uri);
|
||||
|
||||
HttpClient client = newHttpClient(uri, sameClient);
|
||||
|
||||
@ -307,7 +299,7 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
var response = cf.get();
|
||||
System.out.println("Got: " + response);
|
||||
var value = response.headers().firstValue("Header8859").orElse(null);
|
||||
assertEquals(value, "U\u00ffU");
|
||||
assertEquals("U\u00ffU", value);
|
||||
}
|
||||
System.out.println("HttpClient: PASSED");
|
||||
if (uri.contains("http1")) {
|
||||
@ -317,10 +309,10 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
conn.connect();
|
||||
conn.getInputStream().readAllBytes();
|
||||
var value = conn.getHeaderField("Header8859");
|
||||
assertEquals(value, "U\u00ffU", "legacy stack failed");
|
||||
assertEquals("U\u00ffU", value, "legacy stack failed");
|
||||
System.out.println("URLConnection: PASSED");
|
||||
}
|
||||
System.out.println("test: DONE");
|
||||
System.out.println(now() + "test: DONE");
|
||||
}
|
||||
|
||||
static final class DummyServer extends Thread implements AutoCloseable {
|
||||
@ -335,8 +327,8 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
static final InetSocketAddress LOOPBACK =
|
||||
new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
|
||||
final ServerSocket socket;
|
||||
final CopyOnWriteArrayList<Socket> accepted = new CopyOnWriteArrayList<Socket>();
|
||||
final CompletableFuture<Void> done = new CompletableFuture();
|
||||
final CopyOnWriteArrayList<Socket> accepted = new CopyOnWriteArrayList<>();
|
||||
final CompletableFuture<Void> done = new CompletableFuture<>();
|
||||
volatile boolean closed;
|
||||
DummyServer() throws IOException {
|
||||
socket = new ServerSocket();
|
||||
@ -387,11 +379,11 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
final void close(AutoCloseable toclose) {
|
||||
void close(AutoCloseable toclose) {
|
||||
try { toclose.close(); } catch (Exception x) {};
|
||||
}
|
||||
|
||||
final public void close() {
|
||||
public void close() {
|
||||
closed = true;
|
||||
close(socket);
|
||||
accepted.forEach(this::close);
|
||||
@ -410,8 +402,8 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
HttpServerAdapters.HttpTestHandler handler = new ISO88591Handler();
|
||||
InetSocketAddress loopback = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
|
||||
|
||||
@ -448,8 +440,8 @@ public class ISO_8859_1_Test implements HttpServerAdapters {
|
||||
http3TestServer.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
String sharedClientName =
|
||||
sharedClient == null ? null : sharedClient.toString();
|
||||
sharedClient = null;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,34 +27,20 @@
|
||||
* @summary checks that a different proxy returned for
|
||||
* the same host:port is taken into account
|
||||
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
||||
* @build DigestEchoServer ProxySelectorTest jdk.httpclient.test.lib.http2.Http2TestServer
|
||||
* @build DigestEchoServer ProxySelectorTest
|
||||
* jdk.test.lib.net.SimpleSSLContext
|
||||
* @run testng/othervm
|
||||
* @run junit/othervm
|
||||
* -Djdk.http.auth.tunneling.disabledSchemes
|
||||
* -Djdk.httpclient.HttpClient.log=headers,requests
|
||||
* -Djdk.internal.httpclient.debug=true
|
||||
* ProxySelectorTest
|
||||
*/
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.HttpsConfigurator;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.SocketAddress;
|
||||
@ -63,7 +49,6 @@ import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -73,37 +58,44 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
import jdk.httpclient.test.lib.http2.Http2TestServer;
|
||||
|
||||
import static java.lang.System.err;
|
||||
import static java.lang.System.out;
|
||||
import static java.net.http.HttpClient.Version.HTTP_1_1;
|
||||
import static java.net.http.HttpClient.Version.HTTP_2;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ProxySelectorTest implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer httpTestServer; // HTTP/1.1
|
||||
HttpTestServer proxyHttpTestServer; // HTTP/1.1
|
||||
HttpTestServer authProxyHttpTestServer; // HTTP/1.1
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
DigestEchoServer.TunnelingProxy proxy;
|
||||
DigestEchoServer.TunnelingProxy authproxy;
|
||||
String httpURI;
|
||||
String httpsURI;
|
||||
String proxyHttpURI;
|
||||
String authProxyHttpURI;
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
HttpClient client;
|
||||
private static HttpTestServer httpTestServer; // HTTP/1.1
|
||||
private static HttpTestServer proxyHttpTestServer; // HTTP/1.1
|
||||
private static HttpTestServer authProxyHttpTestServer; // HTTP/1.1
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static DigestEchoServer.TunnelingProxy proxy;
|
||||
private static DigestEchoServer.TunnelingProxy authproxy;
|
||||
private static String httpURI;
|
||||
private static String httpsURI;
|
||||
private static String proxyHttpURI;
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static HttpClient client;
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
static final long SLEEP_AFTER_TEST = 0; // milliseconds
|
||||
static final int ITERATIONS = 3;
|
||||
static final Executor executor = new TestExecutor(Executors.newCachedThreadPool());
|
||||
@ -144,34 +136,38 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests() {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
// Exceptions should already have been added to FAILURES
|
||||
@ -204,12 +200,10 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
static final int UNAUTHORIZED = 401;
|
||||
static final int PROXY_UNAUTHORIZED = 407;
|
||||
static final int HTTP_OK = 200;
|
||||
static final String MESSAGE = "Unauthorized";
|
||||
enum Schemes {
|
||||
HTTP, HTTPS
|
||||
}
|
||||
@DataProvider(name = "all")
|
||||
public Object[][] positive() {
|
||||
public static Object[][] positive() {
|
||||
return new Object[][] {
|
||||
{ Schemes.HTTP, HTTP_1_1, httpURI, true},
|
||||
{ Schemes.HTTP, HttpClient.Version.HTTP_2, http2URI, true},
|
||||
@ -222,15 +216,13 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
};
|
||||
}
|
||||
|
||||
static final AtomicLong requestCounter = new AtomicLong();
|
||||
|
||||
static final AtomicLong sleepCount = new AtomicLong();
|
||||
|
||||
@Test(dataProvider = "all")
|
||||
@ParameterizedTest
|
||||
@MethodSource("positive")
|
||||
void test(Schemes scheme, HttpClient.Version version, String uri, boolean async)
|
||||
throws Throwable
|
||||
{
|
||||
checkSkip();
|
||||
var name = String.format("test(%s, %s, %s)", scheme, version, async);
|
||||
out.printf("%n---- starting %s ----%n", name);
|
||||
|
||||
@ -260,7 +252,7 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
HttpRequest request = requestBuilder.build();
|
||||
out.println("Sending request: " + request.uri());
|
||||
|
||||
HttpResponse<T> response = null;
|
||||
HttpResponse<T> response;
|
||||
if (async) {
|
||||
response = client.send(request, handler);
|
||||
} else {
|
||||
@ -288,9 +280,11 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
// A plain server or https server should serve it, and we should get 200 OK
|
||||
response = send(client, uri1, BodyHandlers.ofString(), async);
|
||||
out.println("Got response from plain server: " + response);
|
||||
assertEquals(response.statusCode(), HTTP_OK);
|
||||
assertEquals(response.headers().firstValue("X-value"),
|
||||
scheme == Schemes.HTTPS ? Optional.of("https-server") : Optional.of("plain-server"));
|
||||
assertEquals(HTTP_OK, response.statusCode());
|
||||
assertEquals(scheme == Schemes.HTTPS
|
||||
? Optional.of("https-server")
|
||||
: Optional.of("plain-server"),
|
||||
response.headers().firstValue("X-value"));
|
||||
|
||||
// Second request should go through a non authenticating proxy.
|
||||
// For a clear connection - a proxy-server should serve it, and we should get 200 OK
|
||||
@ -298,9 +292,11 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
// authenticating proxy - and we should receive 200 OK from an https-server
|
||||
response = send(client, uri2, BodyHandlers.ofString(), async);
|
||||
out.println("Got response through noauth proxy: " + response);
|
||||
assertEquals(response.statusCode(), HTTP_OK);
|
||||
assertEquals(response.headers().firstValue("X-value"),
|
||||
scheme == Schemes.HTTPS ? Optional.of("https-server") : Optional.of("proxy-server"));
|
||||
assertEquals(HTTP_OK, response.statusCode());
|
||||
assertEquals(scheme == Schemes.HTTPS
|
||||
? Optional.of("https-server")
|
||||
: Optional.of("proxy-server"),
|
||||
response.headers().firstValue("X-value"));
|
||||
|
||||
// Third request should go through an authenticating proxy.
|
||||
// For a clear connection - an auth-proxy-server should serve it, and we
|
||||
@ -310,16 +306,18 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
// proxy - so the X-value header will be absent
|
||||
response = send(client, uri3, BodyHandlers.ofString(), async);
|
||||
out.println("Got response through auth proxy: " + response);
|
||||
assertEquals(response.statusCode(), PROXY_UNAUTHORIZED);
|
||||
assertEquals(response.headers().firstValue("X-value"),
|
||||
scheme == Schemes.HTTPS ? Optional.empty() : Optional.of("auth-proxy-server"));
|
||||
assertEquals(PROXY_UNAUTHORIZED, response.statusCode());
|
||||
assertEquals(scheme == Schemes.HTTPS
|
||||
? Optional.empty()
|
||||
: Optional.of("auth-proxy-server"),
|
||||
response.headers().firstValue("X-value"));
|
||||
|
||||
}
|
||||
|
||||
// -- Infrastructure
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
httpTestServer = HttpTestServer.create(HTTP_1_1);
|
||||
httpTestServer.addHandler(new PlainServerHandler("plain-server"), "/http1/");
|
||||
httpURI = "http://" + httpTestServer.serverAuthority() + "/http1";
|
||||
@ -368,8 +366,8 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
serverCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
client = null;
|
||||
Thread.sleep(100);
|
||||
AssertionError fail = TRACKER.check(1500);
|
||||
@ -387,7 +385,7 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
class TestProxySelector extends ProxySelector {
|
||||
static final class TestProxySelector extends ProxySelector {
|
||||
@Override
|
||||
public List<Proxy> select(URI uri) {
|
||||
String path = uri.getPath();
|
||||
@ -426,11 +424,8 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
String path = t.getRequestURI().getPath();
|
||||
HttpTestRequestHeaders reqh = t.getRequestHeaders();
|
||||
HttpTestResponseHeaders rsph = t.getResponseHeaders();
|
||||
|
||||
String xValue = serverType;
|
||||
rsph.addHeader("X-value", serverType);
|
||||
|
||||
t.getResponseHeaders().addHeader("X-value", xValue);
|
||||
byte[] body = "RESPONSE".getBytes(UTF_8);
|
||||
t.sendResponseHeaders(HTTP_OK, body.length);
|
||||
try (var out = t.getResponseBody()) {
|
||||
@ -449,20 +444,16 @@ public class ProxySelectorTest implements HttpServerAdapters {
|
||||
@Override
|
||||
public void handle(HttpTestExchange t) throws IOException {
|
||||
readAllRequestData(t); // shouldn't be any
|
||||
String method = t.getRequestMethod();
|
||||
String path = t.getRequestURI().getPath();
|
||||
HttpTestRequestHeaders reqh = t.getRequestHeaders();
|
||||
HttpTestResponseHeaders rsph = t.getResponseHeaders();
|
||||
|
||||
String xValue = serverType;
|
||||
String srv = path.contains("/proxy/") ? "proxy" : "server";
|
||||
String prefix = path.contains("/proxy/") ? "Proxy-" : "WWW-";
|
||||
int code = path.contains("/proxy/") ? PROXY_UNAUTHORIZED : UNAUTHORIZED;
|
||||
String resp = prefix + "Unauthorized";
|
||||
rsph.addHeader(prefix + "Authenticate", "Basic realm=\"earth\", charset=\"UTF-8\"");
|
||||
|
||||
byte[] body = resp.getBytes(UTF_8);
|
||||
t.getResponseHeaders().addHeader("X-value", xValue);
|
||||
rsph.addHeader("X-value", serverType);
|
||||
t.sendResponseHeaders(code, body.length);
|
||||
try (var out = t.getResponseBody()) {
|
||||
out.write(body);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @library /test/lib /test/jdk/java/net/httpclient/lib
|
||||
* @build jdk.test.lib.net.SimpleSSLContext
|
||||
* ReferenceTracker jdk.httpclient.test.lib.common.HttpServerAdapters
|
||||
* @run testng/othervm -Djdk.internal.httpclient.debug=true
|
||||
* @run junit/othervm -Djdk.internal.httpclient.debug=true
|
||||
* -Djdk.httpclient.HttpClient.log=requests,responses,errors
|
||||
* Response204V2Test
|
||||
* @summary Tests that streams are closed after receiving a 204 response.
|
||||
@ -44,7 +44,6 @@ import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.net.http.HttpResponse.BodyHandlers;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
@ -52,19 +51,9 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
@ -74,15 +63,25 @@ import static java.net.http.HttpClient.Version.HTTP_3;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class Response204V2Test implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
String http3URI;
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static String http3URI;
|
||||
|
||||
static final int RESPONSE_CODE = 204;
|
||||
static final int ITERATION_COUNT = 4;
|
||||
@ -101,8 +100,8 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static volatile HttpClient sharedClient;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -128,40 +127,40 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests(ITestContext context) {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static final void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
var failed = context.getFailedTests().getAllResults().stream()
|
||||
.collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable));
|
||||
FAILURES.putAll(failed);
|
||||
|
||||
out.printf("%n%sCreated %d servers and %d clients%n",
|
||||
now(), serverCount.get(), clientCount.get());
|
||||
if (FAILURES.isEmpty()) return;
|
||||
@ -179,7 +178,7 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private String[] uris() {
|
||||
private static String[] uris() {
|
||||
return new String[] {
|
||||
http3URI,
|
||||
http2URI,
|
||||
@ -187,13 +186,7 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
};
|
||||
}
|
||||
|
||||
static AtomicLong URICOUNT = new AtomicLong();
|
||||
|
||||
@DataProvider(name = "variants")
|
||||
public Object[][] variants(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
return new Object[0][];
|
||||
}
|
||||
public static Object[][] variants() {
|
||||
String[] uris = uris();
|
||||
Object[][] result = new Object[uris.length * 2][];
|
||||
int i = 0;
|
||||
@ -232,23 +225,6 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void checkStatus(int expected, int found) throws Exception {
|
||||
if (expected != found) {
|
||||
System.err.printf ("Test failed: wrong status code %d/%d\n",
|
||||
expected, found);
|
||||
throw new RuntimeException("Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkStrings(String expected, String found) throws Exception {
|
||||
if (!expected.equals(found)) {
|
||||
System.err.printf ("Test failed: wrong string %s/%s\n",
|
||||
expected, found);
|
||||
throw new RuntimeException("Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
private HttpRequest.Builder newRequestBuilder(URI uri) {
|
||||
var builder = HttpRequest.newBuilder(uri);
|
||||
if (uri.getRawPath().contains("/http3/")) {
|
||||
@ -258,10 +234,10 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Test(dataProvider = "variants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
public void test(String uri, boolean sameClient) throws Exception {
|
||||
checkSkip();
|
||||
out.println("Request to " + uri);
|
||||
out.printf("%n%s-- test sameClient=%s, uri=%s%n%n", now(), sameClient, uri);
|
||||
|
||||
HttpClient client = newHttpClient(uri, sameClient);
|
||||
|
||||
@ -282,8 +258,8 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
out.println("test: DONE");
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
// HTTP/2
|
||||
HttpTestHandler handler204 = new Handler204();
|
||||
|
||||
@ -305,8 +281,8 @@ public class Response204V2Test implements HttpServerAdapters {
|
||||
http3TestServer.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
String sharedClientName =
|
||||
sharedClient == null ? null : sharedClient.toString();
|
||||
sharedClient = null;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,24 +36,16 @@ import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
@ -64,28 +56,40 @@ import static java.net.http.HttpClient.Builder.NO_PROXY;
|
||||
import static java.net.http.HttpResponse.BodyHandlers.ofString;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public abstract class ShortResponseBody {
|
||||
|
||||
Server closeImmediatelyServer;
|
||||
Server closeImmediatelyHttpsServer;
|
||||
Server variableLengthServer;
|
||||
Server variableLengthHttpsServer;
|
||||
Server fixedLengthServer;
|
||||
private static Server closeImmediatelyServer;
|
||||
private static Server closeImmediatelyHttpsServer;
|
||||
private static Server variableLengthServer;
|
||||
private static Server variableLengthHttpsServer;
|
||||
private static Server fixedLengthServer;
|
||||
|
||||
String httpURIClsImed;
|
||||
String httpsURIClsImed;
|
||||
String httpURIVarLen;
|
||||
String httpsURIVarLen;
|
||||
String httpURIFixLen;
|
||||
private static String httpURIClsImed;
|
||||
private static String httpsURIClsImed;
|
||||
private static String httpURIVarLen;
|
||||
private static String httpsURIVarLen;
|
||||
private static String httpURIFixLen;
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
SSLParameters sslParameters;
|
||||
HttpClient client;
|
||||
int numberOfRequests;
|
||||
private static SSLParameters sslParameters;
|
||||
protected static HttpClient client;
|
||||
private static int numberOfRequests;
|
||||
|
||||
static final int REQUESTS_PER_CLIENT = 10; // create new client every 10 requests
|
||||
static final long PAUSE_FOR_GC = 5; // 5ms to let gc work
|
||||
@ -99,7 +103,7 @@ public abstract class ShortResponseBody {
|
||||
static final AtomicLong reqnb = new AtomicLong();
|
||||
|
||||
static final AtomicLong ids = new AtomicLong();
|
||||
final ThreadFactory factory = new ThreadFactory() {
|
||||
private static final ThreadFactory factory = new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r, "HttpClient-Worker-" + ids.incrementAndGet());
|
||||
@ -107,21 +111,49 @@ public abstract class ShortResponseBody {
|
||||
return thread;
|
||||
}
|
||||
};
|
||||
final ExecutorService service = Executors.newCachedThreadPool(factory);
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
private static final ExecutorService service = Executors.newCachedThreadPool(factory);
|
||||
static final ConcurrentMap<String, Throwable> FAILURES = new ConcurrentHashMap<>();
|
||||
static final long start = System.nanoTime();
|
||||
public static String now() {
|
||||
long now = System.nanoTime() - start;
|
||||
long secs = now / 1000_000_000;
|
||||
long mill = (now % 1000_000_000) / 1000_000;
|
||||
long nan = now % 1000_000;
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@BeforeEach
|
||||
void beforeMethod() {
|
||||
if (client == null || numberOfRequests == REQUESTS_PER_CLIENT) {
|
||||
numberOfRequests = 0;
|
||||
out.println("--- new client");
|
||||
@ -134,22 +166,12 @@ public abstract class ShortResponseBody {
|
||||
}
|
||||
}
|
||||
numberOfRequests++;
|
||||
if (context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests(ITestContext context) {
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================\n");
|
||||
try {
|
||||
var FAILURES = context.getFailedTests().getAllResults().stream()
|
||||
.collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable));
|
||||
|
||||
if (FAILURES.isEmpty()) return;
|
||||
out.println("Failed tests: ");
|
||||
FAILURES.entrySet().forEach((e) -> {
|
||||
@ -162,8 +184,7 @@ public abstract class ShortResponseBody {
|
||||
}
|
||||
}
|
||||
|
||||
@DataProvider(name = "sanity")
|
||||
public Object[][] sanity() {
|
||||
public static Object[][] sanity() {
|
||||
return new Object[][]{
|
||||
{ httpURIVarLen + "?length=all" },
|
||||
{ httpsURIVarLen + "?length=all" },
|
||||
@ -175,22 +196,22 @@ public abstract class ShortResponseBody {
|
||||
return url.replace("%reqnb%", String.valueOf(reqnb.incrementAndGet()));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "sanity")
|
||||
@ParameterizedTest
|
||||
@MethodSource("sanity")
|
||||
void sanity(String url) throws Exception {
|
||||
url = uniqueURL(url);
|
||||
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
|
||||
out.println("Request: " + request);
|
||||
HttpResponse<String> response = client.send(request, ofString());
|
||||
String body = response.body();
|
||||
assertEquals(body, EXPECTED_RESPONSE_BODY);
|
||||
assertEquals(EXPECTED_RESPONSE_BODY, body);
|
||||
client.sendAsync(request, ofString())
|
||||
.thenApply(resp -> resp.body())
|
||||
.thenAccept(b -> assertEquals(b, EXPECTED_RESPONSE_BODY))
|
||||
.thenAccept(b -> assertEquals(EXPECTED_RESPONSE_BODY, b))
|
||||
.join();
|
||||
}
|
||||
|
||||
@DataProvider(name = "sanityBadRequest")
|
||||
public Object[][] sanityBadRequest() {
|
||||
public static Object[][] sanityBadRequest() {
|
||||
return new Object[][]{
|
||||
{ httpURIVarLen }, // no query string
|
||||
{ httpsURIVarLen },
|
||||
@ -198,18 +219,18 @@ public abstract class ShortResponseBody {
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "sanityBadRequest")
|
||||
@ParameterizedTest
|
||||
@MethodSource("sanityBadRequest")
|
||||
void sanityBadRequest(String url) throws Exception {
|
||||
url = uniqueURL(url);
|
||||
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
|
||||
out.println("Request: " + request);
|
||||
HttpResponse<String> response = client.send(request, ofString());
|
||||
assertEquals(response.statusCode(), 400);
|
||||
assertEquals(response.body(), "");
|
||||
assertEquals(400, response.statusCode());
|
||||
assertEquals("", response.body());
|
||||
}
|
||||
|
||||
@DataProvider(name = "uris")
|
||||
public Object[][] variants(ITestContext context) {
|
||||
public static Object[][] variants() {
|
||||
String[][] cases = new String[][] {
|
||||
// The length query string is the total number of bytes in the reply,
|
||||
// including headers, before the server closes the connection. The
|
||||
@ -268,13 +289,6 @@ public abstract class ShortResponseBody {
|
||||
{ httpsURIClsImed, "no bytes"},
|
||||
};
|
||||
|
||||
if (context.getFailedTests().size() > 0) {
|
||||
// Shorten the log output by preventing useless
|
||||
// skip traces to be printed for subsequent methods
|
||||
// if one of the previous @Test method has failed.
|
||||
return new Object[0][];
|
||||
}
|
||||
|
||||
return cases;
|
||||
}
|
||||
|
||||
@ -618,7 +632,7 @@ public abstract class ShortResponseBody {
|
||||
String response( ) { return RESPONSE; }
|
||||
}
|
||||
|
||||
/** A server that issues a, possibly-partial, chunked reply over SSL. */
|
||||
/** A server that issues a possibly-partial, chunked reply over SSL. */
|
||||
static final class SSLVariableLengthServer extends PlainVariableLengthServer {
|
||||
SSLVariableLengthServer() throws IOException {
|
||||
super("SSLVariableLengthServer");
|
||||
@ -655,8 +669,8 @@ public abstract class ShortResponseBody {
|
||||
+ server.getPort();
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
SSLContext.setDefault(sslContext);
|
||||
|
||||
sslParameters = new SSLParameters();
|
||||
@ -682,8 +696,8 @@ public abstract class ShortResponseBody {
|
||||
+ "/http1/fixed/req=%reqnb%/baz";
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
closeImmediatelyServer.close();
|
||||
closeImmediatelyHttpsServer.close();
|
||||
variableLengthServer.close();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,7 +28,7 @@
|
||||
* received before a socket exception or eof.
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.net.SimpleSSLContext ShortResponseBody ShortResponseBodyGet
|
||||
* @run testng/othervm
|
||||
* @run junit/othervm
|
||||
* -Djdk.httpclient.HttpClient.log=headers,errors,channel
|
||||
* ShortResponseBodyGet
|
||||
*/
|
||||
@ -38,21 +38,24 @@ import java.net.URI;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static java.lang.System.out;
|
||||
import static java.net.http.HttpResponse.BodyHandlers.ofString;
|
||||
import static org.testng.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class ShortResponseBodyGet extends ShortResponseBody {
|
||||
|
||||
@Test(dataProvider = "uris")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
void testSynchronousGET(String urlp, String expectedMsg)
|
||||
throws Exception
|
||||
{
|
||||
checkSkip();
|
||||
String url = uniqueURL(urlp);
|
||||
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
|
||||
out.println("Request: " + request);
|
||||
out.printf("%n%s-- testSynchronousGET Request: %s%n%n", now(), request);
|
||||
try {
|
||||
HttpResponse<String> response = client.send(request, ofString());
|
||||
String body = response.body();
|
||||
@ -67,14 +70,14 @@ public class ShortResponseBodyGet extends ShortResponseBody {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "uris")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
void testAsynchronousGET(String urlp, String expectedMsg)
|
||||
throws Exception
|
||||
{
|
||||
checkSkip();
|
||||
String url = uniqueURL(urlp);
|
||||
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
|
||||
out.println("Request: " + request);
|
||||
out.printf("%n%s-- testAsynchronousGET Request: %s%n%n", now(), request);
|
||||
try {
|
||||
HttpResponse<String> response = client.sendAsync(request, ofString()).get();
|
||||
String body = response.body();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,7 +28,7 @@
|
||||
* received before a socket exception or eof.
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.net.SimpleSSLContext ShortResponseBody ShortResponseBodyPost
|
||||
* @run testng/othervm
|
||||
* @run junit/othervm
|
||||
* -Djdk.httpclient.HttpClient.log=headers,errors,channel
|
||||
* -Djdk.internal.httpclient.debug=true
|
||||
* ShortResponseBodyPost
|
||||
@ -42,10 +42,14 @@ import java.net.http.HttpResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static java.lang.System.out;
|
||||
import static java.net.http.HttpResponse.BodyHandlers.ofString;
|
||||
import static org.testng.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class ShortResponseBodyPost extends ShortResponseBody {
|
||||
|
||||
// POST tests are racy in what may be received before writing may cause a
|
||||
@ -56,16 +60,16 @@ public class ShortResponseBodyPost extends ShortResponseBody {
|
||||
List.of("no bytes", "status line", "header");
|
||||
|
||||
|
||||
@Test(dataProvider = "uris")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
void testSynchronousPOST(String urlp, String expectedMsg)
|
||||
throws Exception
|
||||
{
|
||||
checkSkip();
|
||||
String url = uniqueURL(urlp);
|
||||
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
|
||||
.POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
|
||||
.build();
|
||||
out.println("Request: " + request);
|
||||
out.printf("%n%s-- testSynchronousPOST Request: %s%n%n", now(), request);
|
||||
try {
|
||||
HttpResponse<String> response = client.send(request, ofString());
|
||||
String body = response.body();
|
||||
@ -86,16 +90,16 @@ public class ShortResponseBodyPost extends ShortResponseBody {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "uris")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
void testAsynchronousPOST(String urlp, String expectedMsg)
|
||||
throws Exception
|
||||
{
|
||||
checkSkip();
|
||||
String url = uniqueURL(urlp);
|
||||
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
|
||||
.POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
|
||||
.build();
|
||||
out.println("Request: " + request);
|
||||
out.printf("%n%s-- testAsynchronousPOST Request: %s%n%n", now(), request);
|
||||
try {
|
||||
HttpResponse<String> response = client.sendAsync(request, ofString()).get();
|
||||
String body = response.body();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,7 +27,7 @@
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.net.SimpleSSLContext
|
||||
* @build ShortResponseBody ShortResponseBodyPost
|
||||
* @run testng/othervm
|
||||
* @run junit/othervm
|
||||
* -Djdk.httpclient.HttpClient.log=headers,errors,channel
|
||||
* -Djdk.httpclient.enableAllMethodRetry
|
||||
* -Djdk.internal.httpclient.debug=true
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,35 +31,22 @@
|
||||
* jdk.httpclient.test.lib.http2.Http2TestServer
|
||||
* jdk.test.lib.net.SimpleSSLContext
|
||||
* @requires (vm.compMode != "Xcomp")
|
||||
* @run testng/othervm/timeout=480
|
||||
* @run junit/othervm/timeout=480
|
||||
* -Djdk.httpclient.HttpClient.log=requests,headers,errors
|
||||
* SpecialHeadersTest
|
||||
* @run testng/othervm/timeout=480 -Djdk.httpclient.allowRestrictedHeaders=Host
|
||||
* @run junit/othervm/timeout=480 -Djdk.httpclient.allowRestrictedHeaders=Host
|
||||
* -Djdk.httpclient.HttpClient.log=requests,headers,errors
|
||||
* SpecialHeadersTest
|
||||
*/
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.HttpsConfigurator;
|
||||
import com.sun.net.httpserver.HttpsServer;
|
||||
import jdk.internal.net.http.common.OperationTrackers.Tracker;
|
||||
import jdk.test.lib.net.SimpleSSLContext;
|
||||
import org.testng.ITestContext;
|
||||
import org.testng.ITestResult;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpHeaders;
|
||||
@ -83,9 +70,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.httpclient.test.lib.common.HttpServerAdapters;
|
||||
import jdk.httpclient.test.lib.http2.Http2TestServer;
|
||||
|
||||
import static java.lang.System.err;
|
||||
import static java.lang.System.out;
|
||||
@ -93,22 +78,37 @@ import static java.net.http.HttpClient.Builder.NO_PROXY;
|
||||
import static java.net.http.HttpClient.Version.HTTP_1_1;
|
||||
import static java.net.http.HttpClient.Version.HTTP_2;
|
||||
import static java.net.http.HttpClient.Version.HTTP_3;
|
||||
import static java.net.http.HttpOption.H3_DISCOVERY;
|
||||
import static java.net.http.HttpOption.Http3DiscoveryMode.HTTP_3_URI_ONLY;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import org.testng.Assert;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
String httpURI;
|
||||
String httpsURI;
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
private static HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
private static HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer http3TestServer; // HTTP/3
|
||||
private static String httpURI;
|
||||
private static String httpsURI;
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static String https3URI;
|
||||
|
||||
static final String[][] headerNamesAndValues = new String[][]{
|
||||
{"User-Agent: <DEFAULT>"},
|
||||
@ -132,8 +132,7 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
{"hoSt: mixed"}
|
||||
};
|
||||
|
||||
@DataProvider(name = "variants")
|
||||
public Object[][] variants() {
|
||||
public static Object[][] variants() {
|
||||
String prop = System.getProperty("jdk.httpclient.allowRestrictedHeaders");
|
||||
boolean hostTest = prop != null && prop.equalsIgnoreCase("host");
|
||||
final String[][] testInput = hostTest ? headerNamesAndValues1 : headerNamesAndValues;
|
||||
@ -153,6 +152,9 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
Arrays.asList(testInput).stream()
|
||||
.map(e -> new Object[] {https2URI, e[0], sameClient})
|
||||
.forEach(list::add);
|
||||
Arrays.asList(testInput).stream()
|
||||
.map(e -> new Object[] {https3URI, e[0], sameClient})
|
||||
.forEach(list::add);
|
||||
}
|
||||
return list.stream().toArray(Object[][]::new);
|
||||
}
|
||||
@ -173,8 +175,8 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
|
||||
}
|
||||
|
||||
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private volatile HttpClient sharedClient;
|
||||
private static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
|
||||
private static volatile HttpClient sharedClient;
|
||||
|
||||
static class TestExecutor implements Executor {
|
||||
final AtomicLong tasks = new AtomicLong();
|
||||
@ -209,38 +211,39 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
|
||||
}
|
||||
|
||||
protected boolean stopAfterFirstFailure() {
|
||||
private static boolean stopAfterFirstFailure() {
|
||||
return Boolean.getBoolean("jdk.internal.httpclient.debug");
|
||||
}
|
||||
|
||||
final AtomicReference<SkipException> skiptests = new AtomicReference<>();
|
||||
void checkSkip() {
|
||||
var skip = skiptests.get();
|
||||
if (skip != null) throw skip;
|
||||
}
|
||||
static String name(ITestResult result) {
|
||||
var params = result.getParameters();
|
||||
return result.getName()
|
||||
+ (params == null ? "()" : Arrays.toString(result.getParameters()));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
void beforeMethod(ITestContext context) {
|
||||
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
|
||||
if (skiptests.get() == null) {
|
||||
SkipException skip = new SkipException("some tests failed");
|
||||
skip.setStackTrace(new StackTraceElement[0]);
|
||||
skiptests.compareAndSet(null, skip);
|
||||
static final class TestStopper implements TestWatcher, BeforeEachCallback {
|
||||
final AtomicReference<String> failed = new AtomicReference<>();
|
||||
TestStopper() { }
|
||||
@Override
|
||||
public void testFailed(ExtensionContext context, Throwable cause) {
|
||||
if (stopAfterFirstFailure()) {
|
||||
String msg = "Aborting due to: " + cause;
|
||||
failed.compareAndSet(null, msg);
|
||||
FAILURES.putIfAbsent(context.getDisplayName(), cause);
|
||||
System.out.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
System.err.printf("%nTEST FAILED: %s%s%n\tAborting due to %s%n%n",
|
||||
now(), context.getDisplayName(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
String msg = failed.get();
|
||||
Assumptions.assumeTrue(msg == null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static final void printFailedTests(ITestContext context) {
|
||||
@RegisterExtension
|
||||
static final TestStopper stopper = new TestStopper();
|
||||
|
||||
@AfterAll
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
var failed = context.getFailedTests().getAllResults().stream()
|
||||
.collect(Collectors.toMap(r -> name(r), ITestResult::getThrowable));
|
||||
FAILURES.putAll(failed);
|
||||
try {
|
||||
out.printf("%n%sCreated %d servers and %d clients%n",
|
||||
now(), serverCount.get(), clientCount.get());
|
||||
@ -260,7 +263,7 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
|
||||
private HttpClient makeNewClient() {
|
||||
clientCount.incrementAndGet();
|
||||
return HttpClient.newBuilder()
|
||||
return newClientBuilderForH3()
|
||||
.proxy(NO_PROXY)
|
||||
.executor(executor)
|
||||
.sslContext(sslContext)
|
||||
@ -307,7 +310,8 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
if (throwable instanceof Error e) throw e;
|
||||
}
|
||||
|
||||
@Test(dataProvider = "variants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
void test(String uriString,
|
||||
String headerNameAndValue,
|
||||
boolean sameClient)
|
||||
@ -335,6 +339,10 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
}
|
||||
|
||||
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri);
|
||||
if (uriString.contains("/http3")) {
|
||||
requestBuilder.version(HTTP_3);
|
||||
requestBuilder.setOption(H3_DISCOVERY, HTTP_3_URI_ONLY);
|
||||
}
|
||||
if (!useDefault) {
|
||||
requestBuilder.header(name, value);
|
||||
}
|
||||
@ -343,7 +351,7 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
|
||||
out.println("Got response: " + resp);
|
||||
out.println("Got body: " + resp.body());
|
||||
assertEquals(resp.statusCode(), 200,
|
||||
assertEquals(200, resp.statusCode(),
|
||||
"Expected 200, got:" + resp.statusCode());
|
||||
|
||||
boolean isInitialRequest = i == 0;
|
||||
@ -366,10 +374,10 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
: resp.headers().firstValue("X-" + key).get();
|
||||
out.println("Got X-" + key + ": " + resp.headers().allValues("X-" + key));
|
||||
if (value != null) {
|
||||
assertEquals(receivedHeaderString, value);
|
||||
assertEquals(resp.headers().allValues("X-" + key), List.of(value));
|
||||
assertEquals(value, receivedHeaderString);
|
||||
assertEquals(List.of(value), resp.headers().allValues("X-" + key));
|
||||
} else {
|
||||
assertEquals(resp.headers().allValues("X-" + key).size(), 0);
|
||||
assertEquals(0, resp.headers().allValues("X-" + key).size());
|
||||
}
|
||||
}
|
||||
} catch (Throwable x) {
|
||||
@ -389,7 +397,8 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "variants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
void testHomeMadeIllegalHeader(String uriString,
|
||||
String headerNameAndValue,
|
||||
boolean sameClient)
|
||||
@ -443,7 +452,7 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
|
||||
try {
|
||||
HttpResponse<String> response = client.send(req, BodyHandlers.ofString());
|
||||
Assert.fail("Unexpected reply: " + response);
|
||||
Assertions.fail("Unexpected reply: " + response);
|
||||
} catch (IllegalArgumentException ee) {
|
||||
out.println("Got IAE as expected");
|
||||
}
|
||||
@ -465,7 +474,8 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
|
||||
|
||||
|
||||
@Test(dataProvider = "variants")
|
||||
@ParameterizedTest
|
||||
@MethodSource("variants")
|
||||
void testAsync(String uriString, String headerNameAndValue, boolean sameClient)
|
||||
throws Exception
|
||||
{
|
||||
@ -490,6 +500,10 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
}
|
||||
|
||||
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri);
|
||||
if (uriString.contains("/http3")) {
|
||||
requestBuilder.version(HTTP_3);
|
||||
requestBuilder.setOption(H3_DISCOVERY, HTTP_3_URI_ONLY);
|
||||
}
|
||||
if (!useDefault) {
|
||||
requestBuilder.header(name, value);
|
||||
}
|
||||
@ -504,7 +518,7 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
.thenApply(response -> {
|
||||
out.println("Got response: " + response);
|
||||
out.println("Got body: " + response.body());
|
||||
assertEquals(response.statusCode(), 200);
|
||||
assertEquals(200, response.statusCode());
|
||||
return response;
|
||||
})
|
||||
.thenAccept(resp -> {
|
||||
@ -522,10 +536,10 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
: resp.headers().firstValue("X-" + key).orElse(null);
|
||||
out.println("Got X-" + key + ": " + resp.headers().allValues("X-" + key));
|
||||
if (value != null) {
|
||||
assertEquals(receivedHeaderString, value);
|
||||
assertEquals(resp.headers().allValues("X-" + key), List.of(value));
|
||||
assertEquals(value, receivedHeaderString);
|
||||
assertEquals(List.of(value), resp.headers().allValues("X-" + key));
|
||||
} else {
|
||||
assertEquals(resp.headers().allValues("X-" + key).size(), 1);
|
||||
assertEquals(1, resp.headers().allValues("X-" + key).size());
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -552,8 +566,8 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
+ server.getAddress().getPort();
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
public void setup() throws Exception {
|
||||
@BeforeAll
|
||||
public static void setup() throws Exception {
|
||||
out.println("--- Starting setup " + now());
|
||||
|
||||
HttpTestHandler handler = new HttpUriStringHandler();
|
||||
@ -573,14 +587,19 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
https2TestServer.addHandler(handler, "/https2");
|
||||
https2URI = "https://" + https2TestServer.serverAuthority() + "/https2";
|
||||
|
||||
http3TestServer = HttpTestServer.create(HTTP_3_URI_ONLY, sslContext);
|
||||
http3TestServer.addHandler(handler, "/http3");
|
||||
https3URI = "https://" + http3TestServer.serverAuthority() + "/http3";
|
||||
|
||||
httpTestServer.start();
|
||||
httpsTestServer.start();
|
||||
http2TestServer.start();
|
||||
https2TestServer.start();
|
||||
http3TestServer.start();
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void teardown() throws Exception {
|
||||
@AfterAll
|
||||
public static void teardown() throws Exception {
|
||||
out.println("\n--- Teardown " + now());
|
||||
HttpClient shared = sharedClient;
|
||||
String sharedClientName =
|
||||
@ -595,6 +614,7 @@ public class SpecialHeadersTest implements HttpServerAdapters {
|
||||
httpsTestServer.stop();
|
||||
http2TestServer.stop();
|
||||
https2TestServer.stop();
|
||||
http3TestServer.start();
|
||||
executor.shutdown();
|
||||
} finally {
|
||||
if (fail != null) {
|
||||
|
||||
@ -72,20 +72,19 @@ import org.junit.jupiter.api.extension.TestWatcher;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class StreamingBody implements HttpServerAdapters {
|
||||
|
||||
private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
|
||||
HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
String httpURI;
|
||||
String httpsURI;
|
||||
String http2URI;
|
||||
String https2URI;
|
||||
String http3URI;
|
||||
private static HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ]
|
||||
private static HttpTestServer httpsTestServer; // HTTPS/1.1
|
||||
private static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
|
||||
private static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
|
||||
private static HttpTestServer http3TestServer; // HTTP/3 ( h3 )
|
||||
private static String httpURI;
|
||||
private static String httpsURI;
|
||||
private static String http2URI;
|
||||
private static String https2URI;
|
||||
private static String http3URI;
|
||||
|
||||
static final AtomicLong clientCount = new AtomicLong();
|
||||
static final AtomicLong serverCount = new AtomicLong();
|
||||
@ -186,7 +185,7 @@ public class StreamingBody implements HttpServerAdapters {
|
||||
static final String MESSAGE = "StreamingBody message body";
|
||||
static final int ITERATIONS = 100;
|
||||
|
||||
public Object[][] positive() {
|
||||
public static Object[][] positive() {
|
||||
return new Object[][] {
|
||||
{ http3URI, },
|
||||
{ httpURI, },
|
||||
@ -253,7 +252,7 @@ public class StreamingBody implements HttpServerAdapters {
|
||||
// -- Infrastructure
|
||||
|
||||
@BeforeAll
|
||||
public void setup() throws Exception {
|
||||
public static void setup() throws Exception {
|
||||
httpTestServer = HttpTestServer.create(HTTP_1_1);
|
||||
httpTestServer.addHandler(new MessageHandler(), "/http1/streamingbody/");
|
||||
httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/streamingbody/w";
|
||||
@ -290,7 +289,7 @@ public class StreamingBody implements HttpServerAdapters {
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public void teardown() throws Exception {
|
||||
public static void teardown() throws Exception {
|
||||
try {
|
||||
httpTestServer.stop();
|
||||
httpsTestServer.stop();
|
||||
@ -303,7 +302,7 @@ public class StreamingBody implements HttpServerAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
static final void printFailedTests() {
|
||||
static void printFailedTests() {
|
||||
out.println("\n=========================");
|
||||
try {
|
||||
out.printf("%n%sCreated %s servers and %s clients%n",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user