Revised external caching client tests

This commit is contained in:
Oleg Kalnichevski 2023-12-24 11:02:47 +01:00
parent c3d99b130c
commit 810d7b0568
2 changed files with 95 additions and 132 deletions

View File

@ -26,14 +26,10 @@
*/
package org.apache.hc.client5.testing.external;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
@ -48,9 +44,10 @@ import org.apache.hc.client5.http.impl.cache.HeapResourceFactory;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http2.HttpVersionPolicy;
@ -99,26 +96,35 @@ public class CachingHttpAsyncClientCompatibilityTest {
this.client = CachingHttpAsyncClients.custom()
.setCacheConfig(CacheConfig.custom()
.setMaxObjectSize(20480)
.setHeuristicCachingEnabled(true)
.build())
.setResourceFactory(HeapResourceFactory.INSTANCE)
.setConnectionManager(this.connManager)
.build();
}
void shutdown() throws Exception {
client.close();
}
enum TestResult {OK, NOK}
private void logResult(final TestResult result, final HttpRequest request, final String message) {
private void logResult(final TestResult result,
final HttpRequest request,
final HttpResponse response,
final String message) {
final StringBuilder buf = new StringBuilder();
buf.append(result);
if (buf.length() == 2) {
buf.append(" ");
}
buf.append(": ").append(target);
buf.append(": ");
if (response != null && response.getVersion() != null) {
buf.append(response.getVersion()).append(" ");
} else {
buf.append(protocolVersion).append(" ");
}
buf.append(target);
buf.append(": ");
buf.append(request.getMethod()).append(" ").append(request.getRequestUri());
if (message != null && !TextUtils.isBlank(message)) {
@ -127,7 +133,7 @@ public class CachingHttpAsyncClientCompatibilityTest {
System.out.println(buf);
}
void execute() throws Exception {
void execute() throws InterruptedException {
client.start();
// Initial ping
@ -142,113 +148,90 @@ public class CachingHttpAsyncClientCompatibilityTest {
final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final int code = response.getCode();
if (code == HttpStatus.SC_OK) {
logResult(TestResult.OK, options, Objects.toString(response.getFirstHeader("server")));
logResult(TestResult.OK, options, response, Objects.toString(response.getFirstHeader("server")));
} else {
logResult(TestResult.NOK, options, "(status " + code + ")");
logResult(TestResult.NOK, options, response, "(status " + code + ")");
}
} catch (final ExecutionException ex) {
final Throwable cause = ex.getCause();
logResult(TestResult.NOK, options, "(" + cause.getMessage() + ")");
logResult(TestResult.NOK, options, null, "(" + cause.getMessage() + ")");
} catch (final TimeoutException ex) {
logResult(TestResult.NOK, options, "(time out)");
logResult(TestResult.NOK, options, null, "(time out)");
}
}
// GET with links
// GET from cache
{
connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
final HttpCacheContext context = HttpCacheContext.create();
final Pattern linkPattern = Pattern.compile("^<(.*)>;rel=preload$");
final List<String> links = new ArrayList<>();
final SimpleHttpRequest getRoot1 = SimpleRequestBuilder.get()
.setHttpHost(target)
.setPath("/")
.build();
final Future<SimpleHttpResponse> future1 = client.execute(getRoot1, context, null);
try {
final SimpleHttpResponse response = future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) {
logResult(TestResult.OK, getRoot1, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getRoot1, "(status " + code + ", " + cacheResponseStatus + ")");
}
for (final Header header: response.getHeaders("Link")) {
final Matcher matcher = linkPattern.matcher(header.getValue());
if (matcher.matches()) {
links.add(matcher.group(1));
}
}
} catch (final ExecutionException ex) {
final Throwable cause = ex.getCause();
logResult(TestResult.NOK, getRoot1, "(" + cause.getMessage() + ")");
} catch (final TimeoutException ex) {
logResult(TestResult.NOK, getRoot1, "(time out)");
}
final String[] links = {"/", "/css/hc-maven.css", "/images/logos/httpcomponents.png"};
for (final String link: links) {
final SimpleHttpRequest getLink = SimpleRequestBuilder.get()
final SimpleHttpRequest httpGet1 = SimpleRequestBuilder.get()
.setHttpHost(target)
.setPath(link)
.build();
final Future<SimpleHttpResponse> linkFuture = client.execute(getLink, context, null);
final Future<SimpleHttpResponse> linkFuture1 = client.execute(httpGet1, context, null);
try {
final SimpleHttpResponse response = linkFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final SimpleHttpResponse response = linkFuture1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) {
logResult(TestResult.OK, getLink, "200, " + cacheResponseStatus);
logResult(TestResult.OK, httpGet1, response, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getLink, "(status " + code + ", " + cacheResponseStatus + ")");
logResult(TestResult.NOK, httpGet1, response, "(status " + code + ", " + cacheResponseStatus + ")");
}
} catch (final ExecutionException ex) {
final Throwable cause = ex.getCause();
logResult(TestResult.NOK, getLink, "(" + cause.getMessage() + ")");
logResult(TestResult.NOK, httpGet1, null, "(" + cause.getMessage() + ")");
} catch (final TimeoutException ex) {
logResult(TestResult.NOK, getLink, "(time out)");
logResult(TestResult.NOK, httpGet1, null,"(time out)");
}
}
final SimpleHttpRequest getRoot2 = SimpleRequestBuilder.get()
.setHttpHost(target)
.setPath("/")
.build();
final Future<SimpleHttpResponse> future2 = client.execute(getRoot2, context, null);
try {
final SimpleHttpResponse response = future2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) {
logResult(TestResult.OK, getRoot2, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getRoot2, "(status " + code + ", " + cacheResponseStatus + ")");
}
} catch (final ExecutionException ex) {
final Throwable cause = ex.getCause();
logResult(TestResult.NOK, getRoot2, "(" + cause.getMessage() + ")");
} catch (final TimeoutException ex) {
logResult(TestResult.NOK, getRoot2, "(time out)");
}
for (final String link: links) {
final SimpleHttpRequest getLink = SimpleRequestBuilder.get()
final SimpleHttpRequest httpGet2 = SimpleRequestBuilder.get()
.setHttpHost(target)
.setPath(link)
.build();
final Future<SimpleHttpResponse> linkFuture = client.execute(getLink, context, null);
final Future<SimpleHttpResponse> linkFuture2 = client.execute(httpGet2, context, null);
try {
final SimpleHttpResponse response = linkFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final SimpleHttpResponse response = linkFuture2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) {
logResult(TestResult.OK, getLink, "200, " + cacheResponseStatus);
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_HIT) {
logResult(TestResult.OK, httpGet2, response, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getLink, "(status " + code + ", " + cacheResponseStatus + ")");
logResult(TestResult.NOK, httpGet2, response, "(status " + code + ", " + cacheResponseStatus + ")");
}
} catch (final ExecutionException ex) {
final Throwable cause = ex.getCause();
logResult(TestResult.NOK, getLink, "(" + cause.getMessage() + ")");
logResult(TestResult.NOK, httpGet2, null, "(" + cause.getMessage() + ")");
} catch (final TimeoutException ex) {
logResult(TestResult.NOK, getLink, "(time out)");
logResult(TestResult.NOK, httpGet2, null,"(time out)");
}
Thread.sleep(2000);
final SimpleHttpRequest httpGet3 = SimpleRequestBuilder.get()
.setHttpHost(target)
.setPath(link)
.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=0")
.build();
final Future<SimpleHttpResponse> linkFuture3 = client.execute(httpGet3, context, null);
try {
final SimpleHttpResponse response = linkFuture3.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) {
logResult(TestResult.OK, httpGet3, response, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, httpGet3, response, "(status " + code + ", " + cacheResponseStatus + ")");
}
} catch (final ExecutionException ex) {
final Throwable cause = ex.getCause();
logResult(TestResult.NOK, httpGet3, null, "(" + cause.getMessage() + ")");
} catch (final TimeoutException ex) {
logResult(TestResult.NOK, httpGet3, null,"(time out)");
}
}
}

View File

@ -26,11 +26,7 @@
*/
package org.apache.hc.client5.testing.external;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLContext;
@ -46,7 +42,7 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpStatus;
@ -85,6 +81,7 @@ public class CachingHttpClientCompatibilityTest {
this.client = CachingHttpClients.custom()
.setCacheConfig(CacheConfig.custom()
.setMaxObjectSize(20480)
.setHeuristicCachingEnabled(true)
.build())
.setResourceFactory(HeapResourceFactory.INSTANCE)
.setConnectionManager(this.connManager)
@ -112,7 +109,7 @@ public class CachingHttpClientCompatibilityTest {
System.out.println(buf);
}
void execute() {
void execute() throws InterruptedException {
// Initial ping
{
@ -130,73 +127,56 @@ public class CachingHttpClientCompatibilityTest {
logResult(TestResult.NOK, options, "(" + ex.getMessage() + ")");
}
}
// GET with links
// GET from cache
{
connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
final HttpCacheContext context = HttpCacheContext.create();
final Pattern linkPattern = Pattern.compile("^<(.*)>;rel=preload$");
final List<String> links = new ArrayList<>();
final HttpGet getRoot1 = new HttpGet("/");
try (ClassicHttpResponse response = client.executeOpen(target, getRoot1, context)) {
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
EntityUtils.consume(response.getEntity());
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) {
logResult(TestResult.OK, getRoot1, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getRoot1, "(status " + code + ", " + cacheResponseStatus + ")");
}
for (final Header header: response.getHeaders("Link")) {
final Matcher matcher = linkPattern.matcher(header.getValue());
if (matcher.matches()) {
links.add(matcher.group(1));
}
}
} catch (final Exception ex) {
logResult(TestResult.NOK, getRoot1, "(" + ex.getMessage() + ")");
}
final String[] links = {"/", "/css/hc-maven.css", "/images/logos/httpcomponents.png"};
final HttpCacheContext context = HttpCacheContext.create();
for (final String link: links) {
final HttpGet getLink = new HttpGet(link);
try (ClassicHttpResponse response = client.executeOpen(target, getLink, context)) {
final HttpGet httpGet1 = new HttpGet(link);
try (ClassicHttpResponse response = client.executeOpen(target, httpGet1, context)) {
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
EntityUtils.consume(response.getEntity());
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) {
logResult(TestResult.OK, getRoot1, "200, " + cacheResponseStatus);
logResult(TestResult.OK, httpGet1, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getRoot1, "(status " + code + ", " + cacheResponseStatus + ")");
logResult(TestResult.NOK, httpGet1, "(status " + code + ", " + cacheResponseStatus + ")");
}
} catch (final Exception ex) {
logResult(TestResult.NOK, getLink, "(" + ex.getMessage() + ")");
logResult(TestResult.NOK, httpGet1, "(" + ex.getMessage() + ")");
}
}
final HttpGet getRoot2 = new HttpGet("/");
try (ClassicHttpResponse response = client.executeOpen(target, getRoot2, context)) {
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
EntityUtils.consume(response.getEntity());
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) {
logResult(TestResult.OK, getRoot2, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getRoot2, "(status " + code + ", " + cacheResponseStatus + ")");
final HttpGet httpGet2 = new HttpGet(link);
try (ClassicHttpResponse response = client.executeOpen(target, httpGet2, context)) {
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
EntityUtils.consume(response.getEntity());
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_HIT) {
logResult(TestResult.OK, httpGet2, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, httpGet2, "(status " + code + ", " + cacheResponseStatus + ")");
}
} catch (final Exception ex) {
logResult(TestResult.NOK, httpGet2, "(" + ex.getMessage() + ")");
}
} catch (final Exception ex) {
logResult(TestResult.NOK, getRoot2, "(" + ex.getMessage() + ")");
}
for (final String link: links) {
final HttpGet getLink = new HttpGet(link);
try (ClassicHttpResponse response = client.executeOpen(target, getLink, context)) {
Thread.sleep(2000);
final HttpGet httpGet3 = new HttpGet(link);
httpGet3.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=0");
try (ClassicHttpResponse response = client.executeOpen(target, httpGet3, context)) {
final int code = response.getCode();
final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
EntityUtils.consume(response.getEntity());
if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) {
logResult(TestResult.OK, getRoot2, "200, " + cacheResponseStatus);
logResult(TestResult.OK, httpGet3, "200, " + cacheResponseStatus);
} else {
logResult(TestResult.NOK, getRoot2, "(status " + code + ", " + cacheResponseStatus + ")");
logResult(TestResult.NOK, httpGet3, "(status " + code + ", " + cacheResponseStatus + ")");
}
} catch (final Exception ex) {
logResult(TestResult.NOK, getLink, "(" + ex.getMessage() + ")");
logResult(TestResult.NOK, httpGet3, "(" + ex.getMessage() + ")");
}
}
}