2323
2424import jdk .httpclient .test .lib .http3 .Http3TestServer ;
2525import jdk .test .lib .net .SimpleSSLContext ;
26- import org .testng .ITestContext ;
27- import org .testng .ITestResult ;
28- import org .testng .SkipException ;
29- import org .testng .annotations .AfterClass ;
30- import org .testng .annotations .AfterTest ;
31- import org .testng .annotations .BeforeMethod ;
32- import org .testng .annotations .BeforeTest ;
33- import org .testng .annotations .DataProvider ;
3426
3527import javax .net .ssl .SSLContext ;
3628import java .io .IOException ;
4840import java .net .http .HttpResponse .BodyHandlers ;
4941import java .nio .ByteBuffer ;
5042import java .nio .charset .StandardCharsets ;
51- import java .util .Arrays ;
5243import java .util .EnumSet ;
5344import java .util .List ;
5445import java .util .Set ;
6152import java .util .concurrent .Executors ;
6253import java .util .concurrent .Flow ;
6354import java .util .concurrent .SubmissionPublisher ;
55+ import java .util .concurrent .atomic .AtomicBoolean ;
6456import java .util .concurrent .atomic .AtomicLong ;
6557import java .util .concurrent .atomic .AtomicReference ;
6658import java .util .function .BiPredicate ;
7870import static java .net .http .HttpClient .Version .HTTP_3 ;
7971import static java .net .http .HttpOption .H3_DISCOVERY ;
8072import static java .nio .charset .StandardCharsets .UTF_8 ;
81- import static org .testng .Assert .assertEquals ;
82- import static org .testng .Assert .assertTrue ;
73+ import org .junit .jupiter .api .AfterAll ;
74+ import static org .junit .jupiter .api .Assertions .assertEquals ;
75+
76+ import org .junit .jupiter .api .Assumptions ;
77+ import org .junit .jupiter .api .BeforeAll ;
78+ import org .junit .jupiter .api .extension .BeforeEachCallback ;
79+ import org .junit .jupiter .api .extension .ExtensionContext ;
80+ import org .junit .jupiter .api .extension .RegisterExtension ;
81+ import org .junit .jupiter .api .extension .TestWatcher ;
8382
8483public abstract class AbstractThrowingPublishers implements HttpServerAdapters {
8584
86- SSLContext sslContext ;
87- HttpTestServer httpTestServer ; // HTTP/1.1 [ 4 servers ]
88- HttpTestServer httpsTestServer ; // HTTPS/1.1
89- HttpTestServer http2TestServer ; // HTTP/2 ( h2c )
90- HttpTestServer https2TestServer ; // HTTP/2 ( h2 )
91- HttpTestServer http3TestServer ; // HTTP/3 ( h3 )
92- String httpURI_fixed ;
93- String httpURI_chunk ;
94- String httpsURI_fixed ;
95- String httpsURI_chunk ;
96- String http2URI_fixed ;
97- String http2URI_chunk ;
98- String https2URI_fixed ;
99- String https2URI_chunk ;
100- String http3URI_fixed ;
101- String http3URI_chunk ;
102- String http3URI_head ;
85+ static SSLContext sslContext ;
86+ static HttpTestServer httpTestServer ; // HTTP/1.1 [ 4 servers ]
87+ static HttpTestServer httpsTestServer ; // HTTPS/1.1
88+ static HttpTestServer http2TestServer ; // HTTP/2 ( h2c )
89+ static HttpTestServer https2TestServer ; // HTTP/2 ( h2 )
90+ static HttpTestServer http3TestServer ; // HTTP/3 ( h3 )
91+ static String httpURI_fixed ;
92+ static String httpURI_chunk ;
93+ static String httpsURI_fixed ;
94+ static String httpsURI_chunk ;
95+ static String http2URI_fixed ;
96+ static String http2URI_chunk ;
97+ static String https2URI_fixed ;
98+ static String https2URI_chunk ;
99+ static String http3URI_fixed ;
100+ static String http3URI_chunk ;
101+ static String http3URI_head ;
103102
104103 static final int ITERATION_COUNT = 1 ;
105104 // a shared executor helps reduce the amount of threads created by the test
@@ -117,8 +116,34 @@ public static String now() {
117116 return String .format ("[%d s, %d ms, %d ns] " , secs , mill , nan );
118117 }
119118
120- final ReferenceTracker TRACKER = ReferenceTracker .INSTANCE ;
121- private volatile HttpClient sharedClient ;
119+ final static class TestStopper implements TestWatcher , BeforeEachCallback {
120+ final AtomicReference <String > failed = new AtomicReference <>();
121+ TestStopper () { }
122+ @ Override
123+ public void testFailed (ExtensionContext context , Throwable cause ) {
124+ if (stopAfterFirstFailure ()) {
125+ String msg = "Aborting due to: " + cause ;
126+ failed .compareAndSet (null , msg );
127+ FAILURES .putIfAbsent (context .getDisplayName (), cause );
128+ System .out .printf ("%nTEST FAILED: %s%s%n\t Aborting due to %s%n%n" ,
129+ now (), context .getDisplayName (), cause );
130+ System .err .printf ("%nTEST FAILED: %s%s%n\t Aborting due to %s%n%n" ,
131+ now (), context .getDisplayName (), cause );
132+ }
133+ }
134+
135+ @ Override
136+ public void beforeEach (ExtensionContext context ) {
137+ String msg = failed .get ();
138+ Assumptions .assumeTrue (msg == null , msg );
139+ }
140+ }
141+
142+ @ RegisterExtension
143+ static final TestStopper stopper = new TestStopper ();
144+
145+ static final ReferenceTracker TRACKER = ReferenceTracker .INSTANCE ;
146+ private static volatile HttpClient sharedClient ;
122147
123148 static class TestExecutor implements Executor {
124149 final AtomicLong tasks = new AtomicLong ();
@@ -144,21 +169,10 @@ public void execute(Runnable command) {
144169 }
145170 }
146171
147- protected boolean stopAfterFirstFailure () {
172+ protected static boolean stopAfterFirstFailure () {
148173 return Boolean .getBoolean ("jdk.internal.httpclient.debug" );
149174 }
150175
151- final AtomicReference <SkipException > skiptests = new AtomicReference <>();
152- void checkSkip () {
153- var skip = skiptests .get ();
154- if (skip != null ) throw skip ;
155- }
156- static String name (ITestResult result ) {
157- var params = result .getParameters ();
158- return result .getName ()
159- + (params == null ? "()" : Arrays .toString (result .getParameters ()));
160- }
161-
162176 static Version version (String uri ) {
163177 if (uri .contains ("/http1/" ) || uri .contains ("/https1/" ))
164178 return HTTP_1_1 ;
@@ -169,7 +183,7 @@ static Version version(String uri) {
169183 return null ;
170184 }
171185
172- HttpRequest .Builder newRequestBuilder (String uri ) {
186+ static HttpRequest .Builder newRequestBuilder (String uri ) {
173187 var builder = HttpRequest .newBuilder (URI .create (uri ));
174188 if (version (uri ) == HTTP_3 ) {
175189 builder .version (HTTP_3 );
@@ -178,7 +192,7 @@ HttpRequest.Builder newRequestBuilder(String uri) {
178192 return builder ;
179193 }
180194
181- HttpResponse <String > headRequest (HttpClient client )
195+ static HttpResponse <String > headRequest (HttpClient client )
182196 throws IOException , InterruptedException
183197 {
184198 System .out .println ("\n " + now () + "--- Sending HEAD request ----\n " );
@@ -187,26 +201,16 @@ HttpResponse<String> headRequest(HttpClient client)
187201 var request = newRequestBuilder (http3URI_head )
188202 .HEAD ().version (HTTP_2 ).build ();
189203 var response = client .send (request , BodyHandlers .ofString ());
190- assertEquals (response .statusCode (), 200 );
191- assertEquals (response .version (), HTTP_2 );
204+ assertEquals (200 , response .statusCode ());
205+ assertEquals (HTTP_2 , response .version ());
192206 System .out .println ("\n " + now () + "--- HEAD request succeeded ----\n " );
193207 System .err .println ("\n " + now () + "--- HEAD request succeeded ----\n " );
194208 return response ;
195209 }
196210
197- @ BeforeMethod
198- void beforeMethod (ITestContext context ) {
199- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
200- if (skiptests .get () == null ) {
201- SkipException skip = new SkipException ("some tests failed" );
202- skip .setStackTrace (new StackTraceElement [0 ]);
203- skiptests .compareAndSet (null , skip );
204- }
205- }
206- }
207211
208- @ AfterClass
209- static final void printFailedTests (ITestContext context ) {
212+ @ AfterAll
213+ static final void printFailedTests () {
210214 out .println ("\n =========================" );
211215 try {
212216 // Exceptions should already have been added to FAILURES
@@ -230,7 +234,7 @@ static final void printFailedTests(ITestContext context) {
230234 }
231235 }
232236
233- private String [] uris () {
237+ private static String [] uris () {
234238 return new String [] {
235239 http3URI_fixed ,
236240 http3URI_chunk ,
@@ -245,8 +249,7 @@ private String[] uris() {
245249 };
246250 }
247251
248- @ DataProvider (name = "sanity" )
249- public Object [][] sanity () {
252+ public static Object [][] sanity () {
250253 String [] uris = uris ();
251254 Object [][] result = new Object [uris .length * 2 ][];
252255 //Object[][] result = new Object[uris.length][];
@@ -277,7 +280,7 @@ public void accept(Where where) {
277280 }
278281 }
279282
280- private Object [][] variants (List <Thrower > throwers , Set <Where > whereValues ) {
283+ private static Object [][] variants (List <Thrower > throwers , Set <Where > whereValues ) {
281284 String [] uris = uris ();
282285 Object [][] result = new Object [uris .length * 2 * throwers .size ()][];
283286 //Object[][] result = new Object[(uris.length/2) * 2 * 2][];
@@ -296,93 +299,65 @@ private Object[][] variants(List<Thrower> throwers, Set<Where> whereValues) {
296299 return result ;
297300 }
298301
299- @ DataProvider (name = "subscribeProvider" )
300- public Object [][] subscribeProvider (ITestContext context ) {
301- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
302- return new Object [0 ][];
303- }
302+ public static Object [][] subscribeProvider () {
304303 return variants (List .of (
305304 new UncheckedCustomExceptionThrower (),
306305 new UncheckedIOExceptionThrower ()),
307306 EnumSet .of (Where .BEFORE_SUBSCRIBE , Where .AFTER_SUBSCRIBE ));
308307 }
309308
310- @ DataProvider (name = "requestProvider" )
311- public Object [][] requestProvider (ITestContext context ) {
312- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
313- return new Object [0 ][];
314- }
309+ public static Object [][] requestProvider () {
315310 return variants (List .of (
316311 new UncheckedCustomExceptionThrower (),
317312 new UncheckedIOExceptionThrower ()),
318313 EnumSet .of (Where .BEFORE_REQUEST , Where .AFTER_REQUEST ));
319314 }
320315
321- @ DataProvider (name = "nextRequestProvider" )
322- public Object [][] nextRequestProvider (ITestContext context ) {
323- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
324- return new Object [0 ][];
325- }
316+ public static Object [][] nextRequestProvider () {
326317 return variants (List .of (
327318 new UncheckedCustomExceptionThrower (),
328319 new UncheckedIOExceptionThrower ()),
329320 EnumSet .of (Where .BEFORE_NEXT_REQUEST , Where .AFTER_NEXT_REQUEST ));
330321 }
331322
332- @ DataProvider (name = "beforeCancelProviderIO" )
333- public Object [][] beforeCancelProviderIO (ITestContext context ) {
334- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
335- return new Object [0 ][];
336- }
323+ public static Object [][] beforeCancelProviderIO () {
337324 return variants (List .of (
338325 new UncheckedIOExceptionThrower ()),
339326 EnumSet .of (Where .BEFORE_CANCEL ));
340327 }
341328
342- @ DataProvider (name = "afterCancelProviderIO" )
343- public Object [][] afterCancelProviderIO (ITestContext context ) {
344- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
345- return new Object [0 ][];
346- }
329+ public static Object [][] afterCancelProviderIO () {
347330 return variants (List .of (
348331 new UncheckedIOExceptionThrower ()),
349332 EnumSet .of (Where .AFTER_CANCEL ));
350333 }
351334
352- @ DataProvider (name = "beforeCancelProviderCustom" )
353- public Object [][] beforeCancelProviderCustom (ITestContext context ) {
354- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
355- return new Object [0 ][];
356- }
335+ public static Object [][] beforeCancelProviderCustom () {
357336 return variants (List .of (
358337 new UncheckedCustomExceptionThrower ()),
359338 EnumSet .of (Where .BEFORE_CANCEL ));
360339 }
361340
362- @ DataProvider (name = "afterCancelProviderCustom" )
363- public Object [][] afterCancelProvider (ITestContext context ) {
364- if (stopAfterFirstFailure () && context .getFailedTests ().size () > 0 ) {
365- return new Object [0 ][];
366- }
341+ public static Object [][] afterCancelProviderCustom () {
367342 return variants (List .of (
368343 new UncheckedCustomExceptionThrower ()),
369344 EnumSet .of (Where .AFTER_CANCEL ));
370345 }
371346
372- private HttpClient makeNewClient () {
347+ private static HttpClient makeNewClient () {
373348 clientCount .incrementAndGet ();
374- return TRACKER .track (newClientBuilderForH3 ()
349+ return TRACKER .track (HttpServerAdapters . createClientBuilderForH3 ()
375350 .proxy (HttpClient .Builder .NO_PROXY )
376351 .executor (executor )
377352 .sslContext (sslContext )
378353 .build ());
379354 }
380355
381- HttpClient newHttpClient (boolean share ) {
356+ static HttpClient newHttpClient (boolean share ) {
382357 if (!share ) return makeNewClient ();
383358 HttpClient shared = sharedClient ;
384359 if (shared != null ) return shared ;
385- synchronized (this ) {
360+ synchronized (AbstractThrowingPublishers . class ) {
386361 shared = sharedClient ;
387362 if (shared == null ) {
388363 shared = sharedClient = makeNewClient ();
@@ -430,7 +405,7 @@ protected void testSanityImpl(String uri, boolean sameClient)
430405 CompletableFuture <HttpResponse <String >> response = client .sendAsync (req , handler );
431406
432407 String body = response .join ().body ();
433- assertEquals (body , Stream .of (BODY .split ("\\ |" )).collect (Collectors .joining ()));
408+ assertEquals (Stream .of (BODY .split ("\\ |" )).collect (Collectors .joining ()), body );
434409 if (!sameClient ) {
435410 // Wait for the client to be garbage collected.
436411 // we use the ReferenceTracker API rather than HttpClient::close here,
@@ -474,7 +449,6 @@ private <T,U> void testThrowing(String name, String uri, boolean sameClient,
474449 boolean async , Set <Where > whereValues )
475450 throws Exception
476451 {
477- checkSkip ();
478452 out .printf ("%n%s%s%n" , now (), name );
479453 try {
480454 testThrowing (uri , sameClient , publishers , finisher , thrower , async , whereValues );
@@ -778,8 +752,8 @@ public void onError(Throwable throwable) {
778752 }
779753
780754
781- @ BeforeTest
782- public void setup () throws Exception {
755+ @ BeforeAll
756+ public static void setup () throws Exception {
783757 System .out .println (now () + "setup" );
784758 System .err .println (now () + "setup" );
785759
@@ -861,8 +835,8 @@ public void setup() throws Exception {
861835 System .err .println (now () + "setup done" );
862836 }
863837
864- @ AfterTest
865- public void teardown () throws Exception {
838+ @ AfterAll
839+ public static void teardown () throws Exception {
866840 System .out .println (now () + "teardown" );
867841 System .err .println (now () + "teardown" );
868842
0 commit comments