From e5ca77838b9243321ed66afc2f460378d25add63 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Thu, 18 Dec 2025 09:21:37 +0000 Subject: [PATCH] 8373869: Refactor java/net/httpclient/ThrowingPushPromises*.java tests to use JUnit5 Reviewed-by: jpai --- .../AbstractThrowingPushPromises.java | 154 +++++++++--------- ...rowingPushPromisesAsInputStreamCustom.java | 10 +- .../ThrowingPushPromisesAsInputStreamIO.java | 10 +- .../ThrowingPushPromisesAsLinesCustom.java | 10 +- .../ThrowingPushPromisesAsLinesIO.java | 10 +- .../ThrowingPushPromisesAsStringCustom.java | 10 +- .../ThrowingPushPromisesAsStringIO.java | 10 +- .../ThrowingPushPromisesSanity.java | 10 +- 8 files changed, 118 insertions(+), 106 deletions(-) diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java index a7aea89c379..cebcbf2e292 100644 --- a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java +++ b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java @@ -35,18 +35,10 @@ * ReferenceTracker AbstractThrowingPushPromises * jdk.httpclient.test.lib.common.HttpServerAdapters * - * @run testng/othervm -Djdk.internal.httpclient.debug=true + * @run junit/othervm -Djdk.internal.httpclient.debug=true */ 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 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 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 throwers) { + private static Object[][] variants(List 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> 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; diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java index 0b66a8e913e..797507ac7ad 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamCustom.java @@ -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); diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java index 89cf1162bc3..309f60c0f22 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsInputStreamIO.java @@ -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); diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java index d1fb7d34258..77c87151e19 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesCustom.java @@ -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); diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java index 88afaf3dbd5..69deeec533a 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsLinesIO.java @@ -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); diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java index c40af0ab0b0..de38cf4f782 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringCustom.java @@ -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); diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java index 6485e82af8f..ec4d682d73f 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesAsStringIO.java @@ -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); diff --git a/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java b/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java index 7fdb6dcb19d..92f2ab3726d 100644 --- a/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java +++ b/test/jdk/java/net/httpclient/ThrowingPushPromisesSanity.java @@ -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);