Skip to content

Commit d78b4c7

Browse files
committed
8233403: Improve verbosity of some httpclient tests
Improve the verbosity of some httpclient tests to help diagnosis of intermittent failures. Also fixes ShortRequestBody test. Backport-of: eaba9fe
1 parent 8c2cecc commit d78b4c7

5 files changed

+167
-46
lines changed

test/jdk/java/net/httpclient/AbstractThrowingPublishers.java

+42-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
2525
import com.sun.net.httpserver.HttpsConfigurator;
2626
import com.sun.net.httpserver.HttpsServer;
2727
import jdk.testlibrary.SimpleSSLContext;
28+
import org.testng.ITestContext;
2829
import org.testng.annotations.AfterClass;
2930
import org.testng.annotations.AfterTest;
31+
import org.testng.annotations.BeforeMethod;
3032
import org.testng.annotations.BeforeTest;
3133
import org.testng.annotations.DataProvider;
3234
import org.testng.annotations.Test;
@@ -132,6 +134,17 @@ public void execute(Runnable command) {
132134
}
133135
}
134136

137+
protected boolean stopAfterFirstFailure() {
138+
return Boolean.getBoolean("jdk.internal.httpclient.debug");
139+
}
140+
141+
@BeforeMethod
142+
void beforeMethod(ITestContext context) {
143+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
144+
throw new RuntimeException("some tests failed");
145+
}
146+
}
147+
135148
@AfterClass
136149
static final void printFailedTests() {
137150
out.println("\n=========================");
@@ -217,52 +230,73 @@ private Object[][] variants(List<Thrower> throwers, Set<Where> whereValues) {
217230
}
218231

219232
@DataProvider(name = "subscribeProvider")
220-
public Object[][] subscribeProvider() {
233+
public Object[][] subscribeProvider(ITestContext context) {
234+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
235+
return new Object[0][];
236+
}
221237
return variants(List.of(
222238
new UncheckedCustomExceptionThrower(),
223239
new UncheckedIOExceptionThrower()),
224240
EnumSet.of(Where.BEFORE_SUBSCRIBE, Where.AFTER_SUBSCRIBE));
225241
}
226242

227243
@DataProvider(name = "requestProvider")
228-
public Object[][] requestProvider() {
244+
public Object[][] requestProvider(ITestContext context) {
245+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
246+
return new Object[0][];
247+
}
229248
return variants(List.of(
230249
new UncheckedCustomExceptionThrower(),
231250
new UncheckedIOExceptionThrower()),
232251
EnumSet.of(Where.BEFORE_REQUEST, Where.AFTER_REQUEST));
233252
}
234253

235254
@DataProvider(name = "nextRequestProvider")
236-
public Object[][] nextRequestProvider() {
255+
public Object[][] nextRequestProvider(ITestContext context) {
256+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
257+
return new Object[0][];
258+
}
237259
return variants(List.of(
238260
new UncheckedCustomExceptionThrower(),
239261
new UncheckedIOExceptionThrower()),
240262
EnumSet.of(Where.BEFORE_NEXT_REQUEST, Where.AFTER_NEXT_REQUEST));
241263
}
242264

243265
@DataProvider(name = "beforeCancelProviderIO")
244-
public Object[][] beforeCancelProviderIO() {
266+
public Object[][] beforeCancelProviderIO(ITestContext context) {
267+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
268+
return new Object[0][];
269+
}
245270
return variants(List.of(
246271
new UncheckedIOExceptionThrower()),
247272
EnumSet.of(Where.BEFORE_CANCEL));
248273
}
249274

250275
@DataProvider(name = "afterCancelProviderIO")
251-
public Object[][] afterCancelProviderIO() {
276+
public Object[][] afterCancelProviderIO(ITestContext context) {
277+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
278+
return new Object[0][];
279+
}
252280
return variants(List.of(
253281
new UncheckedIOExceptionThrower()),
254282
EnumSet.of(Where.AFTER_CANCEL));
255283
}
256284

257285
@DataProvider(name = "beforeCancelProviderCustom")
258-
public Object[][] beforeCancelProviderCustom() {
286+
public Object[][] beforeCancelProviderCustom(ITestContext context) {
287+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
288+
return new Object[0][];
289+
}
259290
return variants(List.of(
260291
new UncheckedCustomExceptionThrower()),
261292
EnumSet.of(Where.BEFORE_CANCEL));
262293
}
263294

264295
@DataProvider(name = "afterCancelProviderCustom")
265-
public Object[][] afterCancelProvider() {
296+
public Object[][] afterCancelProvider(ITestContext context) {
297+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
298+
return new Object[0][];
299+
}
266300
return variants(List.of(
267301
new UncheckedCustomExceptionThrower()),
268302
EnumSet.of(Where.AFTER_CANCEL));

test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java

+29-6
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@
4141
*/
4242

4343
import jdk.testlibrary.SimpleSSLContext;
44+
import org.testng.ITestContext;
4445
import org.testng.annotations.AfterTest;
4546
import org.testng.annotations.AfterClass;
47+
import org.testng.annotations.BeforeMethod;
4648
import org.testng.annotations.BeforeTest;
4749
import org.testng.annotations.DataProvider;
48-
import org.testng.annotations.Test;
4950

5051
import javax.net.ssl.SSLContext;
5152
import java.io.BufferedReader;
@@ -145,6 +146,17 @@ public void execute(Runnable command) {
145146
}
146147
}
147148

149+
protected boolean stopAfterFirstFailure() {
150+
return Boolean.getBoolean("jdk.internal.httpclient.debug");
151+
}
152+
153+
@BeforeMethod
154+
void beforeMethod(ITestContext context) {
155+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
156+
throw new RuntimeException("some tests failed");
157+
}
158+
}
159+
148160
@AfterClass
149161
static final void printFailedTests() {
150162
out.println("\n=========================");
@@ -207,27 +219,38 @@ public void accept(Where where) {
207219

208220
private Object[][] variants(List<Thrower> throwers) {
209221
String[] uris = uris();
210-
Object[][] result = new Object[uris.length * 2 * throwers.size()][];
222+
// reduce traces by always using the same client if
223+
// stopAfterFirstFailure is requested.
224+
List<Boolean> sameClients = stopAfterFirstFailure()
225+
? List.of(true)
226+
: List.of(false, true);
227+
Object[][] result = new Object[uris.length * sameClients.size() * throwers.size()][];
211228
int i = 0;
212229
for (Thrower thrower : throwers) {
213-
for (boolean sameClient : List.of(false, true)) {
230+
for (boolean sameClient : sameClients) {
214231
for (String uri : uris()) {
215232
result[i++] = new Object[]{uri, sameClient, thrower};
216233
}
217234
}
218235
}
219-
assert i == uris.length * 2 * throwers.size();
236+
assert i == uris.length * sameClients.size() * throwers.size();
220237
return result;
221238
}
222239

223240
@DataProvider(name = "ioVariants")
224-
public Object[][] ioVariants() {
241+
public Object[][] ioVariants(ITestContext context) {
242+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
243+
return new Object[0][];
244+
}
225245
return variants(List.of(
226246
new UncheckedIOExceptionThrower()));
227247
}
228248

229249
@DataProvider(name = "customVariants")
230-
public Object[][] customVariants() {
250+
public Object[][] customVariants(ITestContext context) {
251+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
252+
return new Object[0][];
253+
}
231254
return variants(List.of(
232255
new UncheckedCustomExceptionThrower()));
233256
}

test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
2525
import com.sun.net.httpserver.HttpsConfigurator;
2626
import com.sun.net.httpserver.HttpsServer;
2727
import jdk.testlibrary.SimpleSSLContext;
28+
import org.testng.ITestContext;
2829
import org.testng.annotations.AfterTest;
2930
import org.testng.annotations.AfterClass;
31+
import org.testng.annotations.BeforeMethod;
3032
import org.testng.annotations.BeforeTest;
3133
import org.testng.annotations.DataProvider;
3234
import org.testng.annotations.Test;
@@ -131,6 +133,17 @@ public void execute(Runnable command) {
131133
}
132134
}
133135

136+
protected boolean stopAfterFirstFailure() {
137+
return Boolean.getBoolean("jdk.internal.httpclient.debug");
138+
}
139+
140+
@BeforeMethod
141+
void beforeMethod(ITestContext context) {
142+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
143+
throw new RuntimeException("some tests failed");
144+
}
145+
}
146+
134147
@AfterClass
135148
static final void printFailedTests() {
136149
out.println("\n=========================");
@@ -182,7 +195,10 @@ public Object[][] sanity() {
182195
}
183196

184197
@DataProvider(name = "variants")
185-
public Object[][] variants() {
198+
public Object[][] variants(ITestContext context) {
199+
if (stopAfterFirstFailure() && context.getFailedTests().size() > 0) {
200+
return new Object[0][];
201+
}
186202
String[] uris = uris();
187203
Object[][] result = new Object[uris.length * 2 * 2][];
188204
int i = 0;

test/jdk/java/net/httpclient/ShortRequestBody.java

+46-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
2929
import java.net.InetSocketAddress;
3030
import java.net.ServerSocket;
3131
import java.net.Socket;
32+
import java.net.SocketException;
3233
import java.net.URI;
3334
import java.net.http.HttpClient;
3435
import java.net.http.HttpRequest;
@@ -76,6 +77,7 @@ public class ShortRequestBody {
7677
BYTE_ARRAY_BODY.length,
7778
fileSize(FILE_BODY) };
7879
static final int[] BODY_OFFSETS = new int[] { 0, +1, -1, +2, -2, +3, -3 };
80+
static final String MARKER = "ShortRequestBody";
7981

8082
// A delegating Body Publisher. Subtypes will have a concrete body type.
8183
static abstract class AbstractDelegateRequestBody
@@ -134,7 +136,7 @@ public static void main(String[] args) throws Exception {
134136
try (Server server = new Server()) {
135137
for (Supplier<HttpClient> cs : clientSuppliers) {
136138
err.println("\n---- next supplier ----\n");
137-
URI uri = new URI("http://localhost:" + server.getPort() + "/");
139+
URI uri = new URI("http://localhost:" + server.getPort() + "/" + MARKER);
138140

139141
// sanity ( 6 requests to keep client and server offsets easy to workout )
140142
success(cs, uri, new StringRequestBody(STRING_BODY, 0));
@@ -248,44 +250,56 @@ public void run() {
248250
int offset = 0;
249251

250252
while (!closed) {
253+
err.println("Server: waiting for connection");
251254
try (Socket s = ss.accept()) {
252255
err.println("Server: got connection");
253256
InputStream is = s.getInputStream();
254-
readRequestHeaders(is);
257+
try {
258+
String headers = readRequestHeaders(is);
259+
if (headers == null) continue;
260+
} catch (SocketException ex) {
261+
err.println("Ignoring unexpected exception while reading headers: " + ex);
262+
ex.printStackTrace(err);
263+
// proceed in order to update count etc..., even though
264+
// we know that read() will fail;
265+
}
255266
byte[] ba = new byte[1024];
256267

257268
int length = BODY_LENGTHS[count % 3];
258269
length += BODY_OFFSETS[offset];
259270
err.println("Server: count=" + count + ", offset=" + offset);
260271
err.println("Server: expecting " +length+ " bytes");
261-
int read = is.readNBytes(ba, 0, length);
262-
err.println("Server: actually read " + read + " bytes");
263-
264-
// Update the counts before replying, to prevent the
265-
// client-side racing reset with this thread.
266-
count++;
267-
if (count % 6 == 0) // 6 is the number of failure requests per offset
268-
offset++;
269-
if (count % 42 == 0) {
270-
count = 0; // reset, for second iteration
271-
offset = 0;
272+
int read = 0;
273+
try {
274+
read = is.readNBytes(ba, 0, length);
275+
err.println("Server: actually read " + read + " bytes");
276+
} finally {
277+
// Update the counts before replying, to prevent the
278+
// client-side racing reset with this thread.
279+
count++;
280+
if (count % 6 == 0) // 6 is the number of failure requests per offset
281+
offset++;
282+
if (count % 42 == 0) {
283+
count = 0; // reset, for second iteration
284+
offset = 0;
285+
}
272286
}
273-
274287
if (read < length) {
275288
// no need to reply, client has already closed
276289
// ensure closed
277290
if (is.read() != -1)
278-
new AssertionError("Unexpected read");
291+
new AssertionError("Unexpected read: " + read);
279292
} else {
280293
OutputStream os = s.getOutputStream();
281294
err.println("Server: writing "
282295
+ RESPONSE.getBytes(US_ASCII).length + " bytes");
283296
os.write(RESPONSE.getBytes(US_ASCII));
284297
}
285-
286-
} catch (IOException e) {
287-
if (!closed)
288-
System.out.println("Unexpected" + e);
298+
} catch (Throwable e) {
299+
if (!closed) {
300+
err.println("Unexpected: " + e);
301+
e.printStackTrace();
302+
}
289303
}
290304
}
291305
}
@@ -306,9 +320,14 @@ public void close() {
306320
static final byte[] requestEnd = new byte[] {'\r', '\n', '\r', '\n' };
307321

308322
// Read until the end of a HTTP request headers
309-
static void readRequestHeaders(InputStream is) throws IOException {
310-
int requestEndCount = 0, r;
323+
static String readRequestHeaders(InputStream is) throws IOException {
324+
int requestEndCount = 0, r, eol = -1;
325+
StringBuilder headers = new StringBuilder();
311326
while ((r = is.read()) != -1) {
327+
if (r == '\r' && eol < 0) {
328+
eol = headers.length();
329+
}
330+
headers.append((char) r);
312331
if (r == requestEnd[requestEndCount]) {
313332
requestEndCount++;
314333
if (requestEndCount == 4) {
@@ -318,6 +337,11 @@ static void readRequestHeaders(InputStream is) throws IOException {
318337
requestEndCount = 0;
319338
}
320339
}
340+
341+
if (eol <= 0) return null;
342+
String requestLine = headers.toString().substring(0, eol);
343+
if (!requestLine.contains(MARKER)) return null;
344+
return headers.toString();
321345
}
322346

323347
static int fileSize(Path p) {

0 commit comments

Comments
 (0)