8373869: Refactor java/net/httpclient/ThrowingPushPromises*.java tests to use JUnit5

Reviewed-by: jpai
This commit is contained in:
Daniel Fuchs 2025-12-18 09:21:37 +00:00
parent 3f20eb9435
commit e5ca77838b
8 changed files with 118 additions and 106 deletions

View File

@ -35,18 +35,10 @@
* ReferenceTracker AbstractThrowingPushPromises
* jdk.httpclient.test.lib.common.HttpServerAdapters
* <concrete-class-name>
* @run testng/othervm -Djdk.internal.httpclient.debug=true <concrete-class-name>
* @run junit/othervm -Djdk.internal.httpclient.debug=true <concrete-class-name>
*/
import jdk.test.lib.net.SimpleSSLContext;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.SkipException;
import org.testng.annotations.AfterTest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
@ -100,21 +92,32 @@ 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.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.BeforeEach;
import org.junit.jupiter.api.TestInstance;
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;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class AbstractThrowingPushPromises implements HttpServerAdapters {
SSLContext sslContext;
HttpTestServer http2TestServer; // HTTP/2 ( h2c )
HttpTestServer https2TestServer; // HTTP/2 ( h2 )
HttpTestServer http3TestServer; // HTTP/3 ( h3 )
String http2URI_fixed;
String http2URI_chunk;
String https2URI_fixed;
String https2URI_chunk;
String http3URI_fixed;
String http3URI_chunk;
static SSLContext sslContext;
static HttpTestServer http2TestServer; // HTTP/2 ( h2c )
static HttpTestServer https2TestServer; // HTTP/2 ( h2 )
static HttpTestServer http3TestServer; // HTTP/3 ( h3 )
static String http2URI_fixed;
static String http2URI_chunk;
static String https2URI_fixed;
static String https2URI_chunk;
static String http3URI_fixed;
static String http3URI_chunk;
static final int ITERATION_COUNT = 1;
// a shared executor helps reduce the amount of threads created by the test
@ -132,8 +135,34 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
return String.format("[%d s, %d ms, %d ns] ", secs, mill, nan);
}
final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
private volatile HttpClient sharedClient;
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();
static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
private static volatile HttpClient sharedClient;
static class TestExecutor implements Executor {
final AtomicLong tasks = new AtomicLong();
@ -159,34 +188,13 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
}
}
protected boolean stopAfterFirstFailure() {
protected 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);
}
}
}
@AfterClass
static final void printFailedTests(ITestContext context) {
@AfterAll
static final void printFailedTests() {
out.println("\n=========================");
try {
// Exceptions should already have been added to FAILURES
@ -211,7 +219,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
}
}
private String[] uris() {
private static String[] uris() {
return new String[] {
http3URI_fixed,
http3URI_chunk,
@ -222,8 +230,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
};
}
@DataProvider(name = "sanity")
public Object[][] sanity() {
public static Object[][] sanity() {
String[] uris = uris();
Object[][] result = new Object[uris.length * 2][];
@ -252,7 +259,7 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
}
}
private Object[][] variants(List<Thrower> throwers) {
private static Object[][] variants(List<Thrower> throwers) {
String[] uris = uris();
// reduce traces by always using the same client if
// stopAfterFirstFailure is requested.
@ -272,27 +279,19 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
return result;
}
@DataProvider(name = "ioVariants")
public Object[][] ioVariants(ITestContext context) {
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
return new Object[0][];
}
public static Object[][] ioVariants() {
return variants(List.of(
new UncheckedIOExceptionThrower()));
}
@DataProvider(name = "customVariants")
public Object[][] customVariants(ITestContext context) {
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
return new Object[0][];
}
public static Object[][] customVariants() {
return variants(List.of(
new UncheckedCustomExceptionThrower()));
}
private HttpClient makeNewClient() {
private static HttpClient makeNewClient() {
clientCount.incrementAndGet();
return TRACKER.track(newClientBuilderForH3()
return TRACKER.track(HttpServerAdapters.createClientBuilderForH3()
.version(HTTP_3)
.proxy(HttpClient.Builder.NO_PROXY)
.executor(executor)
@ -300,11 +299,11 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
.build());
}
HttpClient newHttpClient(boolean share) {
static HttpClient newHttpClient(boolean share) {
if (!share) return makeNewClient();
HttpClient shared = sharedClient;
if (shared != null) return shared;
synchronized (this) {
synchronized (AbstractThrowingPushPromises.class) {
shared = sharedClient;
if (shared == null) {
shared = sharedClient = makeNewClient();
@ -313,15 +312,15 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
}
}
Http3DiscoveryMode config(String uri) {
static Http3DiscoveryMode config(String uri) {
return uri.contains("/http3/") ? HTTP_3_URI_ONLY : null;
}
Version version(String uri) {
static Version version(String uri) {
return uri.contains("/http3/") ? HTTP_3 : HTTP_2;
}
HttpRequest request(String uri) {
static HttpRequest request(String uri) {
var builder = HttpRequest.newBuilder(URI.create(uri))
.version(version(uri));
var config = config(uri);
@ -358,15 +357,15 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
HttpResponse<Stream<String>> response =
client.sendAsync(req, BodyHandlers.ofLines(), pushHandler).get();
String body = response.body().collect(Collectors.joining("|"));
assertEquals(URI.create(body).getPath(), URI.create(uri).getPath());
assertEquals(URI.create(uri).getPath(), URI.create(body).getPath());
for (HttpRequest promised : pushPromises.keySet()) {
out.printf("%s Received promise: %s%n\tresponse: %s%n",
now(), promised, pushPromises.get(promised).get());
String promisedBody = pushPromises.get(promised).get().body()
.collect(Collectors.joining("|"));
assertEquals(promisedBody, promised.uri().toASCIIString());
assertEquals(promised.uri().toASCIIString(), promisedBody);
}
assertEquals(pushPromises.size(), 3);
assertEquals(3, pushPromises.size());
if (!sameClient) {
// Wait for the client to be garbage collected.
// we use the ReferenceTracker API rather than HttpClient::close here,
@ -429,7 +428,6 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
Finisher finisher, Thrower thrower)
throws Exception
{
checkSkip();
out.printf("%n%s%s%n", now(), name);
try {
testThrowing(uri, sameClient, handlers, finisher, thrower);
@ -603,9 +601,9 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
default:
expectedCount = 3;
}
assertEquals(promises.size(), expectedCount,
assertEquals(expectedCount, promises.size(),
"bad promise count for " + reqURI + " with " + w);
assertEquals(result, List.of(reqURI.toASCIIString()));
assertEquals(List.of(reqURI.toASCIIString()), result);
return result;
}
@ -758,8 +756,8 @@ public abstract class AbstractThrowingPushPromises implements HttpServerAdapters
}
@BeforeTest
public void setup() throws Exception {
@BeforeAll
public static void setup() throws Exception {
sslContext = new SimpleSSLContext().get();
if (sslContext == null)
throw new AssertionError("Unexpected null sslContext");
@ -792,8 +790,8 @@ public abstract class AbstractThrowingPushPromises 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;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -30,14 +30,16 @@
* @build jdk.test.lib.net.SimpleSSLContext
* ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsInputStreamCustom
* jdk.httpclient.test.lib.common.HttpServerAdapters
* @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsInputStreamCustom
* @run junit/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsInputStreamCustom
*/
import org.testng.annotations.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ThrowingPushPromisesAsInputStreamCustom extends AbstractThrowingPushPromises {
@Test(dataProvider = "customVariants")
@ParameterizedTest
@MethodSource("customVariants")
public void testThrowingAsInputStream(String uri, boolean sameClient, Thrower thrower)
throws Exception {
super.testThrowingAsInputStreamImpl(uri, sameClient, thrower);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -30,14 +30,16 @@
* @build jdk.test.lib.net.SimpleSSLContext
* ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsInputStreamIO
* jdk.httpclient.test.lib.common.HttpServerAdapters
* @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsInputStreamIO
* @run junit/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsInputStreamIO
*/
import org.testng.annotations.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ThrowingPushPromisesAsInputStreamIO extends AbstractThrowingPushPromises {
@Test(dataProvider = "ioVariants")
@ParameterizedTest
@MethodSource("ioVariants")
public void testThrowingAsInputStream(String uri, boolean sameClient, Thrower thrower)
throws Exception {
super.testThrowingAsInputStreamImpl(uri, sameClient, thrower);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -30,14 +30,16 @@
* @build jdk.test.lib.net.SimpleSSLContext
* ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsLinesCustom
* jdk.httpclient.test.lib.common.HttpServerAdapters
* @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsLinesCustom
* @run junit/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsLinesCustom
*/
import org.testng.annotations.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ThrowingPushPromisesAsLinesCustom extends AbstractThrowingPushPromises {
@Test(dataProvider = "customVariants")
@ParameterizedTest
@MethodSource("customVariants")
public void testThrowingAsLines(String uri, boolean sameClient, Thrower thrower)
throws Exception {
super.testThrowingAsLinesImpl(uri, sameClient, thrower);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -30,14 +30,16 @@
* @build jdk.test.lib.net.SimpleSSLContext
* ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsLinesIO
* jdk.httpclient.test.lib.common.HttpServerAdapters
* @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsLinesIO
* @run junit/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsLinesIO
*/
import org.testng.annotations.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ThrowingPushPromisesAsLinesIO extends AbstractThrowingPushPromises {
@Test(dataProvider = "ioVariants")
@ParameterizedTest
@MethodSource("ioVariants")
public void testThrowingAsLines(String uri, boolean sameClient, Thrower thrower)
throws Exception {
super.testThrowingAsLinesImpl(uri, sameClient, thrower);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -30,14 +30,16 @@
* @build jdk.test.lib.net.SimpleSSLContext
* ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsStringCustom
* jdk.httpclient.test.lib.common.HttpServerAdapters
* @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsStringCustom
* @run junit/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsStringCustom
*/
import org.testng.annotations.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ThrowingPushPromisesAsStringCustom extends AbstractThrowingPushPromises {
@Test(dataProvider = "customVariants")
@ParameterizedTest
@MethodSource("customVariants")
public void testThrowingAsString(String uri, boolean sameClient, Thrower thrower)
throws Exception {
super.testThrowingAsStringImpl(uri, sameClient, thrower);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -30,14 +30,16 @@
* @build jdk.test.lib.net.SimpleSSLContext
* ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesAsStringIO
* jdk.httpclient.test.lib.common.HttpServerAdapters
* @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsStringIO
* @run junit/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesAsStringIO
*/
import org.testng.annotations.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ThrowingPushPromisesAsStringIO extends AbstractThrowingPushPromises {
@Test(dataProvider = "ioVariants")
@ParameterizedTest
@MethodSource("ioVariants")
public void testThrowingAsString(String uri, boolean sameClient, Thrower thrower)
throws Exception {
super.testThrowingAsStringImpl(uri, sameClient, thrower);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -30,14 +30,16 @@
* @build jdk.test.lib.net.SimpleSSLContext
* ReferenceTracker AbstractThrowingPushPromises ThrowingPushPromisesSanity
* jdk.httpclient.test.lib.common.HttpServerAdapters
* @run testng/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesSanity
* @run junit/othervm -Djdk.internal.httpclient.debug=true ThrowingPushPromisesSanity
*/
import org.testng.annotations.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ThrowingPushPromisesSanity extends AbstractThrowingPushPromises {
@Test(dataProvider = "sanity")
@ParameterizedTest
@MethodSource("sanity")
public void testSanity(String uri, boolean sameClient)
throws Exception {
super.testSanityImpl(uri, sameClient);