Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8266900: java/net/httpclient/ShortResponseBody.java fails on windows …
…with java.io.IOException: Unable to establish loopback connection

Reviewed-by: dfuchs
  • Loading branch information
djelinski committed Oct 24, 2022
1 parent aad81f2 commit 329b49a
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 140 deletions.
51 changes: 17 additions & 34 deletions test/jdk/java/net/httpclient/ShortResponseBody.java
Expand Up @@ -34,7 +34,6 @@
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
Expand All @@ -44,6 +43,7 @@
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;
Expand Down Expand Up @@ -84,7 +84,10 @@ public abstract class ShortResponseBody {

SSLContext sslContext;
SSLParameters sslParameters;
HttpClient client;
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
static final long PAUSE_FOR_PEER = 5; // 5ms to let server react

Expand Down Expand Up @@ -119,12 +122,18 @@ static String name(ITestResult result) {

@BeforeMethod
void beforeMethod(ITestContext context) {
System.gc();
try {
Thread.sleep(PAUSE_FOR_GC);
} catch (InterruptedException x) {
if (client == null || numberOfRequests == REQUESTS_PER_CLIENT) {
numberOfRequests = 0;
out.println("--- new client");
client = newHttpClient();
System.gc();
try {
Thread.sleep(PAUSE_FOR_GC);
} catch (InterruptedException x) {

}
}
numberOfRequests++;
if (context.getFailedTests().size() > 0) {
if (skiptests.get() == null) {
SkipException skip = new SkipException("some tests failed");
Expand Down Expand Up @@ -168,7 +177,6 @@ public static String uniqueURL(String url) {

@Test(dataProvider = "sanity")
void sanity(String url) throws Exception {
HttpClient client = newHttpClient();
url = uniqueURL(url);
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
out.println("Request: " + request);
Expand All @@ -192,7 +200,6 @@ public Object[][] sanityBadRequest() {

@Test(dataProvider = "sanityBadRequest")
void sanityBadRequest(String url) throws Exception {
HttpClient client = newHttpClient();
url = uniqueURL(url);
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
out.println("Request: " + request);
Expand Down Expand Up @@ -268,18 +275,9 @@ public Object[][] variants(ITestContext context) {
return new Object[0][];
}

List<Object[]> list = new ArrayList<>();
Arrays.asList(cases).stream()
.map(e -> new Object[] {e[0], e[1], true}) // reuse client
.forEach(list::add);
Arrays.asList(cases).stream()
.map(e -> new Object[] {e[0], e[1], false}) // do not reuse client
.forEach(list::add);
return list.stream().toArray(Object[][]::new);
return cases;
}

static final int ITERATION_COUNT = 3;

HttpClient newHttpClient() {
return HttpClient.newBuilder()
.proxy(NO_PROXY)
Expand All @@ -289,18 +287,6 @@ HttpClient newHttpClient() {
.build();
}

HttpClient sharedClient = null;
HttpClient newHttpClient(boolean shared) {
if (shared) {
HttpClient sharedClient = this.sharedClient;
if (sharedClient == null) {
sharedClient = this.sharedClient = newHttpClient();
}
return sharedClient;
}
return newHttpClient();
}

// can be used to prolong request body publication
static final class InfiniteInputStream extends InputStream {
int count = 0;
Expand Down Expand Up @@ -555,10 +541,8 @@ public void run() {
private static void writeResponse(Socket socket, String response, int len) throws IOException {
OutputStream os = socket.getOutputStream();
byte[] responseBytes = response.getBytes(US_ASCII);
for (int i = 0; i < len; ++i) {
os.write(responseBytes[i]);
os.flush();
}
os.write(responseBytes, 0, len);
os.flush();
}

static final byte[] requestEnd = new byte[] { '\r', '\n', '\r', '\n' };
Expand Down Expand Up @@ -703,7 +687,6 @@ public void setup() throws Exception {

@AfterTest
public void teardown() throws Exception {
if (sharedClient != null) sharedClient = null;
closeImmediatelyServer.close();
closeImmediatelyHttpsServer.close();
variableLengthServer.close();
Expand Down
79 changes: 32 additions & 47 deletions test/jdk/java/net/httpclient/ShortResponseBodyGet.java
Expand Up @@ -35,74 +35,59 @@

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.ExecutionException;
import org.testng.annotations.Test;
import static java.lang.System.out;
import static java.net.http.HttpResponse.BodyHandlers.ofString;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

public class ShortResponseBodyGet extends ShortResponseBody {

@Test(dataProvider = "uris")
void testSynchronousGET(String urlp, String expectedMsg, boolean sameClient)
void testSynchronousGET(String urlp, String expectedMsg)
throws Exception
{
checkSkip();
out.print("---\n");
HttpClient client = null;
for (int i=0; i< ITERATION_COUNT; i++) {
String url = uniqueURL(urlp);
if (client == null)
client = newHttpClient(sameClient);
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.send(request, ofString());
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (IOException ioe) {
out.println("Caught expected exception:" + ioe);
assertExpectedMessage(request, ioe, expectedMsg);
// synchronous API must have the send method on the stack
assertSendMethodOnStack(ioe);
assertNoConnectionExpiredException(ioe);
}
String url = uniqueURL(urlp);
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.send(request, ofString());
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (IOException ioe) {
out.println("Caught expected exception:" + ioe);
assertExpectedMessage(request, ioe, expectedMsg);
// synchronous API must have the send method on the stack
assertSendMethodOnStack(ioe);
assertNoConnectionExpiredException(ioe);
}
}

@Test(dataProvider = "uris")
void testAsynchronousGET(String urlp, String expectedMsg, boolean sameClient)
void testAsynchronousGET(String urlp, String expectedMsg)
throws Exception
{
checkSkip();
out.print("---\n");
HttpClient client = null;
for (int i=0; i< ITERATION_COUNT; i++) {
String url = uniqueURL(urlp);
if (client == null)
client = newHttpClient(sameClient);
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.sendAsync(request, ofString()).get();
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (ExecutionException ee) {
if (ee.getCause() instanceof IOException) {
IOException ioe = (IOException) ee.getCause();
out.println("Caught expected exception:" + ioe);
assertExpectedMessage(request, ioe, expectedMsg);
assertNoConnectionExpiredException(ioe);
} else {
throw ee;
}
String url = uniqueURL(urlp);
HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.sendAsync(request, ofString()).get();
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (ExecutionException ee) {
if (ee.getCause() instanceof IOException) {
IOException ioe = (IOException) ee.getCause();
out.println("Caught expected exception:" + ioe);
assertExpectedMessage(request, ioe, expectedMsg);
assertNoConnectionExpiredException(ioe);
} else {
throw ee;
}
}
}
Expand Down
103 changes: 44 additions & 59 deletions test/jdk/java/net/httpclient/ShortResponseBodyPost.java
Expand Up @@ -36,7 +36,6 @@

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
Expand All @@ -46,8 +45,6 @@
import org.testng.annotations.Test;
import static java.lang.System.out;
import static java.net.http.HttpResponse.BodyHandlers.ofString;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
public class ShortResponseBodyPost extends ShortResponseBody {

Expand All @@ -60,76 +57,64 @@ public class ShortResponseBodyPost extends ShortResponseBody {


@Test(dataProvider = "uris")
void testSynchronousPOST(String urlp, String expectedMsg, boolean sameClient)
void testSynchronousPOST(String urlp, String expectedMsg)
throws Exception
{
checkSkip();
out.print("---\n");
HttpClient client = null;
for (int i=0; i< ITERATION_COUNT; i++) {
String url = uniqueURL(urlp);
if (client == null)
client = newHttpClient(sameClient);
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
.build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.send(request, ofString());
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (IOException ioe) {
out.println("Caught expected exception:" + ioe);
String url = uniqueURL(urlp);
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
.build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.send(request, ofString());
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (IOException ioe) {
out.println("Caught expected exception:" + ioe);

List<String> expectedMessages = new ArrayList<>();
expectedMessages.add(expectedMsg);
MSGS_ORDER.stream().takeWhile(s -> !s.equals(expectedMsg))
.forEach(expectedMessages::add);
List<String> expectedMessages = new ArrayList<>();
expectedMessages.add(expectedMsg);
MSGS_ORDER.stream().takeWhile(s -> !s.equals(expectedMsg))
.forEach(expectedMessages::add);

assertExpectedMessage(request, ioe, expectedMessages);
// synchronous API must have the send method on the stack
assertSendMethodOnStack(ioe);
assertNoConnectionExpiredException(ioe);
}
assertExpectedMessage(request, ioe, expectedMessages);
// synchronous API must have the send method on the stack
assertSendMethodOnStack(ioe);
assertNoConnectionExpiredException(ioe);
}
}

@Test(dataProvider = "uris")
void testAsynchronousPOST(String urlp, String expectedMsg, boolean sameClient)
void testAsynchronousPOST(String urlp, String expectedMsg)
throws Exception
{
checkSkip();
out.print("---\n");
HttpClient client = null;
for (int i=0; i< ITERATION_COUNT; i++) {
String url = uniqueURL(urlp);
if (client == null)
client = newHttpClient(sameClient);
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
.build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.sendAsync(request, ofString()).get();
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (ExecutionException ee) {
if (ee.getCause() instanceof IOException) {
IOException ioe = (IOException) ee.getCause();
out.println("Caught expected exception:" + ioe);
String url = uniqueURL(urlp);
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.POST(BodyPublishers.ofInputStream(() -> new InfiniteInputStream()))
.build();
out.println("Request: " + request);
try {
HttpResponse<String> response = client.sendAsync(request, ofString()).get();
String body = response.body();
out.println(response + ": " + body);
fail("UNEXPECTED RESPONSE: " + response);
} catch (ExecutionException ee) {
if (ee.getCause() instanceof IOException) {
IOException ioe = (IOException) ee.getCause();
out.println("Caught expected exception:" + ioe);

List<String> expectedMessages = new ArrayList<>();
expectedMessages.add(expectedMsg);
MSGS_ORDER.stream().takeWhile(s -> !s.equals(expectedMsg))
.forEach(expectedMessages::add);
List<String> expectedMessages = new ArrayList<>();
expectedMessages.add(expectedMsg);
MSGS_ORDER.stream().takeWhile(s -> !s.equals(expectedMsg))
.forEach(expectedMessages::add);

assertExpectedMessage(request, ioe, expectedMessages);
assertNoConnectionExpiredException(ioe);
} else {
throw ee;
}
assertExpectedMessage(request, ioe, expectedMessages);
assertNoConnectionExpiredException(ioe);
} else {
throw ee;
}
}
}
Expand Down

1 comment on commit 329b49a

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.