From 1a626dc00ca017f40c4be999fafcb6217f7428c3 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 11 Jan 2024 13:12:19 +0100 Subject: [PATCH 01/10] CI: db startup options --- docker/start_db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/start_db.sh b/docker/start_db.sh index 5d537ec6d..b857962fd 100755 --- a/docker/start_db.sh +++ b/docker/start_db.sh @@ -65,7 +65,7 @@ docker run -d \ --starter.address="${GW}" \ --docker.image="${DOCKER_IMAGE}" \ --starter.local --starter.mode=${STARTER_MODE} --all.log.level=debug --all.log.output=+ --log.verbose \ - --all.server.descriptors-minimum=1024 --all.javascript.allow-admin-execute=true + --all.server.descriptors-minimum=1024 --all.javascript.allow-admin-execute=true --all.http.compress-response-threshold=1 wait_server() { From d8ffcc2d2642145415428330d1768f0c22494140 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 11 Jan 2024 13:13:13 +0100 Subject: [PATCH 02/10] added compression configuration options --- core/src/main/java/com/arangodb/ArangoDB.java | 38 +++++++++++++++++++ .../main/java/com/arangodb/Compression.java | 7 ++++ .../config/ArangoConfigProperties.java | 13 +++++++ .../com/arangodb/internal/ArangoDefaults.java | 7 ++++ .../internal/config/ArangoConfig.java | 31 +++++++++++++++ .../config/ArangoConfigPropertiesImpl.java | 16 ++++++++ .../java/com/arangodb/ArangoConfigTest.java | 35 +++++++++++++++++ .../java/mp/ArangoConfigPropertiesMPImpl.java | 26 ++++++++++++- .../test/java/mp/ConfigMPDefaultsTest.java | 3 ++ driver/src/test/java/mp/ConfigMPTest.java | 7 ++++ .../resources/arangodb-config-test.properties | 4 +- 11 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/com/arangodb/Compression.java create mode 100644 driver/src/test/java/com/arangodb/ArangoConfigTest.java diff --git a/core/src/main/java/com/arangodb/ArangoDB.java b/core/src/main/java/com/arangodb/ArangoDB.java index 466df4653..e455eff01 100644 --- a/core/src/main/java/com/arangodb/ArangoDB.java +++ b/core/src/main/java/com/arangodb/ArangoDB.java @@ -627,6 +627,44 @@ public Builder asyncExecutor(final Executor executor) { return this; } + /** + * Sets the {@code content-encoding} and {@code accept-encoding} to use for HTTP requests and the related + * algorithm to encode and decode the transferred data. (default: {@link Compression#NONE}) + * + * @param compression format + * @return {@link ArangoDB.Builder} + * @since ArangoDB 3.12 + */ + public Builder compression(final Compression compression) { + config.setCompression(compression); + return this; + } + + /** + * Sets the minimum HTTP request body size (in bytes) to trigger compression. + * (default: {@code 1024}) + * + * @param threshold body size (in bytes) + * @return {@link ArangoDB.Builder} + * @since ArangoDB 3.12 + */ + public Builder compressionThreshold(Integer threshold) { + config.setCompressionThreshold(threshold); + return this; + } + + /** + * Sets the compression level. (default: {@code 6}) + * + * @param level compression level + * @return {@link ArangoDB.Builder} + * @since ArangoDB 3.12 + */ + public Builder compressionLevel(Integer level) { + config.setCompressionLevel(level); + return this; + } + @UnstableApi protected ProtocolProvider protocolProvider(Protocol protocol) { ServiceLoader loader = ServiceLoader.load(ProtocolProvider.class); diff --git a/core/src/main/java/com/arangodb/Compression.java b/core/src/main/java/com/arangodb/Compression.java new file mode 100644 index 000000000..d18d13d60 --- /dev/null +++ b/core/src/main/java/com/arangodb/Compression.java @@ -0,0 +1,7 @@ +package com.arangodb; + +public enum Compression { + NONE, + DEFLATE, + GZIP +} diff --git a/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java b/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java index 5ef63676f..47c464a1e 100644 --- a/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java +++ b/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java @@ -1,5 +1,6 @@ package com.arangodb.config; +import com.arangodb.Compression; import com.arangodb.Protocol; import com.arangodb.entity.LoadBalancingStrategy; import com.arangodb.internal.config.ArangoConfigPropertiesImpl; @@ -97,4 +98,16 @@ default Optional getResponseQueueTimeSamples() { return Optional.empty(); } + default Optional getCompression() { + return Optional.empty(); + } + + default Optional getCompressionThreshold() { + return Optional.empty(); + } + + default Optional getCompressionLevel() { + return Optional.empty(); + } + } diff --git a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java index aab635dd3..de813aa94 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java +++ b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java @@ -20,6 +20,7 @@ package com.arangodb.internal; +import com.arangodb.Compression; import com.arangodb.Protocol; import com.arangodb.config.HostDescription; import com.arangodb.entity.LoadBalancingStrategy; @@ -53,6 +54,12 @@ public final class ArangoDefaults { public static final LoadBalancingStrategy DEFAULT_LOAD_BALANCING_STRATEGY = LoadBalancingStrategy.NONE; public static final Integer DEFAULT_RESPONSE_QUEUE_TIME_SAMPLES = 10; + // region compression + public static final Compression DEFAULT_COMPRESSION = Compression.NONE; + public static final Integer DEFAULT_COMPRESSION_THRESHOLD = 1024; + public static final Integer DEFAULT_COMPRESSION_LEVEL = 6; + // endregion + private ArangoDefaults() { super(); } diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java index 814d40d25..73befd8c0 100644 --- a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java +++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java @@ -1,6 +1,7 @@ package com.arangodb.internal.config; import com.arangodb.ArangoDBException; +import com.arangodb.Compression; import com.arangodb.ContentType; import com.arangodb.Protocol; import com.arangodb.arch.UsedInApi; @@ -45,6 +46,9 @@ public class ArangoConfig { private Integer responseQueueTimeSamples; private Module protocolModule; private Executor asyncExecutor; + private Compression compression; + private Integer compressionThreshold; + private Integer compressionLevel; private static final Logger LOG = LoggerFactory.getLogger(ArangoConfig.class); @@ -97,6 +101,9 @@ public void loadProperties(final ArangoConfigProperties properties) { acquireHostListInterval = properties.getAcquireHostListInterval().orElse(ArangoDefaults.DEFAULT_ACQUIRE_HOST_LIST_INTERVAL); loadBalancingStrategy = properties.getLoadBalancingStrategy().orElse(ArangoDefaults.DEFAULT_LOAD_BALANCING_STRATEGY); responseQueueTimeSamples = properties.getResponseQueueTimeSamples().orElse(ArangoDefaults.DEFAULT_RESPONSE_QUEUE_TIME_SAMPLES); + compression = properties.getCompression().orElse(ArangoDefaults.DEFAULT_COMPRESSION); + compressionThreshold = properties.getCompressionThreshold().orElse(ArangoDefaults.DEFAULT_COMPRESSION_THRESHOLD); + compressionLevel = properties.getCompressionLevel().orElse(ArangoDefaults.DEFAULT_COMPRESSION_LEVEL); } public List getHosts() { @@ -287,4 +294,28 @@ public Executor getAsyncExecutor() { public void setAsyncExecutor(Executor asyncExecutor) { this.asyncExecutor = asyncExecutor; } + + public Compression getCompression() { + return compression; + } + + public void setCompression(Compression compression) { + this.compression = compression; + } + + public Integer getCompressionThreshold() { + return compressionThreshold; + } + + public void setCompressionThreshold(Integer compressionThreshold) { + this.compressionThreshold = compressionThreshold; + } + + public Integer getCompressionLevel() { + return compressionLevel; + } + + public void setCompressionLevel(Integer compressionLevel) { + this.compressionLevel = compressionLevel; + } } diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java index df51a0a6b..279fb2ba0 100644 --- a/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java +++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java @@ -1,6 +1,7 @@ package com.arangodb.internal.config; import com.arangodb.ArangoDBException; +import com.arangodb.Compression; import com.arangodb.Protocol; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.config.HostDescription; @@ -145,4 +146,19 @@ public Optional getResponseQueueTimeSamples() { return Optional.ofNullable(getProperty("responseQueueTimeSamples")).map(Integer::valueOf); } + @Override + public Optional getCompression() { + return Optional.ofNullable(getProperty("compression")).map(Compression::valueOf); + } + + @Override + public Optional getCompressionThreshold() { + return Optional.ofNullable(getProperty("compressionThreshold")).map(Integer::valueOf); + } + + @Override + public Optional getCompressionLevel() { + return Optional.ofNullable(getProperty("compressionLevel")).map(Integer::valueOf); + } + } diff --git a/driver/src/test/java/com/arangodb/ArangoConfigTest.java b/driver/src/test/java/com/arangodb/ArangoConfigTest.java new file mode 100644 index 000000000..d0e32ae26 --- /dev/null +++ b/driver/src/test/java/com/arangodb/ArangoConfigTest.java @@ -0,0 +1,35 @@ +package com.arangodb; + +import com.arangodb.internal.ArangoDefaults; +import com.arangodb.internal.config.ArangoConfig; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ArangoConfigTest { + @Test + void defaultValues() { + ArangoConfig cfg = new ArangoConfig(); + assertThat(cfg.getHosts()).isEqualTo(ArangoDefaults.DEFAULT_HOSTS); + assertThat(cfg.getProtocol()).isEqualTo(Protocol.HTTP2_JSON); + assertThat(cfg.getTimeout()).isEqualTo(ArangoDefaults.DEFAULT_TIMEOUT); + assertThat(cfg.getUser()).isEqualTo(ArangoDefaults.DEFAULT_USER); + assertThat(cfg.getPassword()).isNull(); + assertThat(cfg.getJwt()).isNull(); + assertThat(cfg.getUseSsl()).isEqualTo(ArangoDefaults.DEFAULT_USE_SSL); + assertThat(cfg.getSslContext()).isNull(); + assertThat(cfg.getVerifyHost()).isEqualTo(ArangoDefaults.DEFAULT_VERIFY_HOST); + assertThat(cfg.getChunkSize()).isEqualTo(ArangoDefaults.DEFAULT_CHUNK_SIZE); + assertThat(cfg.getMaxConnections()).isEqualTo(ArangoDefaults.MAX_CONNECTIONS_HTTP2_DEFAULT); + assertThat(cfg.getConnectionTtl()).isNull(); + assertThat(cfg.getKeepAliveInterval()).isNull(); + assertThat(cfg.getAcquireHostList()).isEqualTo(ArangoDefaults.DEFAULT_ACQUIRE_HOST_LIST); + assertThat(cfg.getAcquireHostListInterval()).isEqualTo(ArangoDefaults.DEFAULT_ACQUIRE_HOST_LIST_INTERVAL); + assertThat(cfg.getLoadBalancingStrategy()).isEqualTo(ArangoDefaults.DEFAULT_LOAD_BALANCING_STRATEGY); + assertThat(cfg.getResponseQueueTimeSamples()).isEqualTo(ArangoDefaults.DEFAULT_RESPONSE_QUEUE_TIME_SAMPLES); + assertThat(cfg.getAsyncExecutor()).isNull(); + assertThat(cfg.getCompression()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION); + assertThat(cfg.getCompressionThreshold()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_THRESHOLD); + assertThat(cfg.getCompressionLevel()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_LEVEL); + } +} diff --git a/driver/src/test/java/mp/ArangoConfigPropertiesMPImpl.java b/driver/src/test/java/mp/ArangoConfigPropertiesMPImpl.java index 21f6fe850..3f4120e12 100644 --- a/driver/src/test/java/mp/ArangoConfigPropertiesMPImpl.java +++ b/driver/src/test/java/mp/ArangoConfigPropertiesMPImpl.java @@ -1,5 +1,6 @@ package mp; +import com.arangodb.Compression; import com.arangodb.Protocol; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.config.HostDescription; @@ -29,6 +30,9 @@ public final class ArangoConfigPropertiesMPImpl implements ArangoConfigPropertie private Optional acquireHostListInterval; private Optional loadBalancingStrategy; private Optional responseQueueTimeSamples; + private Optional compression; + private Optional compressionThreshold; + private Optional compressionLevel; @Override public Optional> getHosts() { @@ -110,17 +114,32 @@ public Optional getResponseQueueTimeSamples() { return responseQueueTimeSamples; } + @Override + public Optional getCompression() { + return compression; + } + + @Override + public Optional getCompressionThreshold() { + return compressionThreshold; + } + + @Override + public Optional getCompressionLevel() { + return compressionLevel; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ArangoConfigPropertiesMPImpl that = (ArangoConfigPropertiesMPImpl) o; - return Objects.equals(hosts, that.hosts) && Objects.equals(protocol, that.protocol) && Objects.equals(user, that.user) && Objects.equals(password, that.password) && Objects.equals(jwt, that.jwt) && Objects.equals(timeout, that.timeout) && Objects.equals(useSsl, that.useSsl) && Objects.equals(verifyHost, that.verifyHost) && Objects.equals(chunkSize, that.chunkSize) && Objects.equals(maxConnections, that.maxConnections) && Objects.equals(connectionTtl, that.connectionTtl) && Objects.equals(keepAliveInterval, that.keepAliveInterval) && Objects.equals(acquireHostList, that.acquireHostList) && Objects.equals(acquireHostListInterval, that.acquireHostListInterval) && Objects.equals(loadBalancingStrategy, that.loadBalancingStrategy) && Objects.equals(responseQueueTimeSamples, that.responseQueueTimeSamples); + return Objects.equals(hosts, that.hosts) && Objects.equals(protocol, that.protocol) && Objects.equals(user, that.user) && Objects.equals(password, that.password) && Objects.equals(jwt, that.jwt) && Objects.equals(timeout, that.timeout) && Objects.equals(useSsl, that.useSsl) && Objects.equals(verifyHost, that.verifyHost) && Objects.equals(chunkSize, that.chunkSize) && Objects.equals(maxConnections, that.maxConnections) && Objects.equals(connectionTtl, that.connectionTtl) && Objects.equals(keepAliveInterval, that.keepAliveInterval) && Objects.equals(acquireHostList, that.acquireHostList) && Objects.equals(acquireHostListInterval, that.acquireHostListInterval) && Objects.equals(loadBalancingStrategy, that.loadBalancingStrategy) && Objects.equals(responseQueueTimeSamples, that.responseQueueTimeSamples) && Objects.equals(compression, that.compression) && Objects.equals(compressionThreshold, that.compressionThreshold) && Objects.equals(compressionLevel, that.compressionLevel); } @Override public int hashCode() { - return Objects.hash(hosts, protocol, user, password, jwt, timeout, useSsl, verifyHost, chunkSize, maxConnections, connectionTtl, keepAliveInterval, acquireHostList, acquireHostListInterval, loadBalancingStrategy, responseQueueTimeSamples); + return Objects.hash(hosts, protocol, user, password, jwt, timeout, useSsl, verifyHost, chunkSize, maxConnections, connectionTtl, keepAliveInterval, acquireHostList, acquireHostListInterval, loadBalancingStrategy, responseQueueTimeSamples, compression, compressionThreshold, compressionLevel); } @Override @@ -142,6 +161,9 @@ public String toString() { ", acquireHostListInterval=" + acquireHostListInterval + ", loadBalancingStrategy=" + loadBalancingStrategy + ", responseQueueTimeSamples=" + responseQueueTimeSamples + + ", compression=" + compression + + ", compressionThreshold=" + compressionThreshold + + ", compressionLevel=" + compressionLevel + '}'; } } diff --git a/driver/src/test/java/mp/ConfigMPDefaultsTest.java b/driver/src/test/java/mp/ConfigMPDefaultsTest.java index 5e32807c2..3ff81bd04 100644 --- a/driver/src/test/java/mp/ConfigMPDefaultsTest.java +++ b/driver/src/test/java/mp/ConfigMPDefaultsTest.java @@ -32,6 +32,9 @@ private void checkResult(ArangoConfigProperties config) { assertThat(config.getAcquireHostListInterval()).isEmpty(); assertThat(config.getLoadBalancingStrategy()).isEmpty(); assertThat(config.getResponseQueueTimeSamples()).isEmpty(); + assertThat(config.getCompression()).isEmpty(); + assertThat(config.getCompressionThreshold()).isNotPresent(); + assertThat(config.getCompressionLevel()).isNotPresent(); } } diff --git a/driver/src/test/java/mp/ConfigMPTest.java b/driver/src/test/java/mp/ConfigMPTest.java index c26c26171..06bb8f254 100644 --- a/driver/src/test/java/mp/ConfigMPTest.java +++ b/driver/src/test/java/mp/ConfigMPTest.java @@ -1,5 +1,6 @@ package mp; +import com.arangodb.Compression; import com.arangodb.Protocol; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.config.HostDescription; @@ -29,6 +30,9 @@ class ConfigMPTest { private final Integer acquireHostListInterval = 1234567; private final LoadBalancingStrategy loadBalancingStrategy = LoadBalancingStrategy.ROUND_ROBIN; private final Integer responseQueueTimeSamples = 12345678; + private final Compression compression = Compression.GZIP; + private final Integer compressionThreshold = 123456789; + private final Integer compressionLevel = 9; @Test void readConfig() { @@ -66,5 +70,8 @@ private void checkResult(ArangoConfigProperties config) { assertThat(config.getAcquireHostListInterval()).hasValue(acquireHostListInterval); assertThat(config.getLoadBalancingStrategy()).hasValue(loadBalancingStrategy); assertThat(config.getResponseQueueTimeSamples()).hasValue(responseQueueTimeSamples); + assertThat(config.getCompression()).hasValue(compression); + assertThat(config.getCompressionThreshold()).hasValue(compressionThreshold); + assertThat(config.getCompressionLevel()).hasValue(compressionLevel); } } diff --git a/driver/src/test/resources/arangodb-config-test.properties b/driver/src/test/resources/arangodb-config-test.properties index 48fe4f1ed..e93668c93 100644 --- a/driver/src/test/resources/arangodb-config-test.properties +++ b/driver/src/test/resources/arangodb-config-test.properties @@ -14,4 +14,6 @@ adb.acquireHostList=true adb.acquireHostListInterval=1234567 adb.loadBalancingStrategy=ROUND_ROBIN adb.responseQueueTimeSamples=12345678 - +adb.compression=GZIP +adb.compressionThreshold=123456789 +adb.compressionLevel=9 From 5fa72504416ff98912595a54fd0e2217950dd3f8 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 11 Jan 2024 14:18:30 +0100 Subject: [PATCH 03/10] added content encoding compression to HttpConnection --- core/src/main/java/com/arangodb/ArangoDB.java | 2 +- .../com/arangodb/http/HttpConnection.java | 52 +++-- .../arangodb/http/compression/Encoder.java | 28 +++ .../http/compression/JdkZlibEncoder.java | 192 ++++++++++++++++++ .../http/compression/NoopEncoder.java | 15 ++ .../http/compression/ZlibEncoder.java | 31 +++ 6 files changed, 301 insertions(+), 19 deletions(-) create mode 100644 http/src/main/java/com/arangodb/http/compression/Encoder.java create mode 100644 http/src/main/java/com/arangodb/http/compression/JdkZlibEncoder.java create mode 100644 http/src/main/java/com/arangodb/http/compression/NoopEncoder.java create mode 100644 http/src/main/java/com/arangodb/http/compression/ZlibEncoder.java diff --git a/core/src/main/java/com/arangodb/ArangoDB.java b/core/src/main/java/com/arangodb/ArangoDB.java index e455eff01..3fe94fe2e 100644 --- a/core/src/main/java/com/arangodb/ArangoDB.java +++ b/core/src/main/java/com/arangodb/ArangoDB.java @@ -656,7 +656,7 @@ public Builder compressionThreshold(Integer threshold) { /** * Sets the compression level. (default: {@code 6}) * - * @param level compression level + * @param level compression level between 0 and 9 * @return {@link ArangoDB.Builder} * @since ArangoDB 3.12 */ diff --git a/http/src/main/java/com/arangodb/http/HttpConnection.java b/http/src/main/java/com/arangodb/http/HttpConnection.java index e2711921a..9c62497b9 100644 --- a/http/src/main/java/com/arangodb/http/HttpConnection.java +++ b/http/src/main/java/com/arangodb/http/HttpConnection.java @@ -20,12 +20,10 @@ package com.arangodb.http; -import com.arangodb.ArangoDBException; -import com.arangodb.ContentType; -import com.arangodb.PackageVersion; -import com.arangodb.Protocol; +import com.arangodb.*; import com.arangodb.arch.UnstableApi; import com.arangodb.config.HostDescription; +import com.arangodb.http.compression.Encoder; import com.arangodb.internal.InternalRequest; import com.arangodb.internal.InternalResponse; import com.arangodb.internal.RequestType; @@ -37,6 +35,7 @@ import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.IdentityCipherSuiteFilter; import io.netty.handler.ssl.JdkSslContext; +import io.vertx.core.MultiMap; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.buffer.Buffer; @@ -75,10 +74,12 @@ public class HttpConnection implements Connection { private static final String CONTENT_TYPE_VPACK = "application/x-velocypack"; private static final String USER_AGENT = getUserAgent(); private static final AtomicInteger THREAD_COUNT = new AtomicInteger(); - private final ContentType contentType; private String auth; + private final int compressionThreshold; + private final Encoder encoder; private final WebClient client; private final Integer timeout; + private final MultiMap commonHeaders = MultiMap.caseInsensitiveMultiMap(); private final Vertx vertx; private static String getUserAgent() { @@ -88,7 +89,23 @@ private static String getUserAgent() { HttpConnection(final ArangoConfig config, final HostDescription host) { super(); Protocol protocol = config.getProtocol(); - contentType = ContentTypeFactory.of(protocol); + ContentType contentType = ContentTypeFactory.of(protocol); + if (contentType == ContentType.VPACK) { + commonHeaders.add(HttpHeaders.ACCEPT.toString(), CONTENT_TYPE_VPACK); + commonHeaders.add(HttpHeaders.CONTENT_TYPE.toString(), CONTENT_TYPE_VPACK); + } else if (contentType == ContentType.JSON) { + commonHeaders.add(HttpHeaders.ACCEPT.toString(), CONTENT_TYPE_APPLICATION_JSON_UTF8); + commonHeaders.add(HttpHeaders.CONTENT_TYPE.toString(), CONTENT_TYPE_APPLICATION_JSON_UTF8); + } else { + throw new IllegalArgumentException("Unsupported protocol: " + protocol); + } + compressionThreshold = config.getCompressionThreshold(); + Compression compression = config.getCompression(); + encoder = Encoder.of(compression, config.getCompressionLevel()); + if (encoder.getFormat() != null) { + commonHeaders.add(HttpHeaders.ACCEPT_ENCODING.toString(), encoder.getFormat()); + } + commonHeaders.add("x-arango-driver", USER_AGENT); timeout = config.getTimeout(); vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true).setEventLoopPoolSize(1)); vertx.runOnContext(e -> { @@ -127,6 +144,9 @@ private static String getUserAgent() { .setDefaultHost(host.getHost()) .setDefaultPort(host.getPort()); + if (compression != Compression.NONE) { + webClientOptions.setTryUseCompression(true); + } if (Boolean.TRUE.equals(config.getUseSsl())) { SSLContext ctx; @@ -236,24 +256,20 @@ public void doExecute(@UnstableApi final InternalRequest request, @UnstableApi f HttpRequest httpRequest = client .request(requestTypeToHttpMethod(request.getRequestType()), path) .timeout(timeout); - if (contentType == ContentType.VPACK) { - httpRequest.putHeader("Accept", CONTENT_TYPE_VPACK); - } + + httpRequest.putHeaders(commonHeaders); addHeader(request, httpRequest); httpRequest.putHeader(HttpHeaders.AUTHORIZATION.toString(), auth); - httpRequest.putHeader("x-arango-driver", USER_AGENT); byte[] reqBody = request.getBody(); Buffer buffer; - if (reqBody != null) { - buffer = Buffer.buffer(reqBody); - if (contentType == ContentType.VPACK) { - httpRequest.putHeader(HttpHeaders.CONTENT_TYPE.toString(), CONTENT_TYPE_VPACK); - } else { - httpRequest.putHeader(HttpHeaders.CONTENT_TYPE.toString(), CONTENT_TYPE_APPLICATION_JSON_UTF8); - } - } else { + if (reqBody == null) { buffer = Buffer.buffer(); + } else if (reqBody.length > compressionThreshold) { + httpRequest.putHeader(HttpHeaders.CONTENT_ENCODING.toString(), encoder.getFormat()); + buffer = encoder.encode(reqBody); + } else { + buffer = Buffer.buffer(reqBody); } try { diff --git a/http/src/main/java/com/arangodb/http/compression/Encoder.java b/http/src/main/java/com/arangodb/http/compression/Encoder.java new file mode 100644 index 000000000..840999265 --- /dev/null +++ b/http/src/main/java/com/arangodb/http/compression/Encoder.java @@ -0,0 +1,28 @@ +package com.arangodb.http.compression; + +import com.arangodb.Compression; +import io.netty.handler.codec.compression.ZlibWrapper; +import io.vertx.core.buffer.Buffer; + +public interface Encoder { + Buffer encode(byte[] data); + + String getFormat(); + + static Encoder of(Compression compression, int level) { + if (level < 0 || level > 9) { + throw new IllegalArgumentException("compression level: " + level + " (expected: 0-9)"); + } + + switch (compression) { + case GZIP: + return new ZlibEncoder(ZlibWrapper.GZIP, level, "gzip"); + case DEFLATE: + return new ZlibEncoder(ZlibWrapper.ZLIB, level, "deflate"); + case NONE: + return new NoopEncoder(); + default: + throw new IllegalArgumentException("Unsupported compression: " + compression); + } + } +} diff --git a/http/src/main/java/com/arangodb/http/compression/JdkZlibEncoder.java b/http/src/main/java/com/arangodb/http/compression/JdkZlibEncoder.java new file mode 100644 index 000000000..fff071926 --- /dev/null +++ b/http/src/main/java/com/arangodb/http/compression/JdkZlibEncoder.java @@ -0,0 +1,192 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.arangodb.http.compression; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.handler.codec.compression.CompressionException; +import io.netty.handler.codec.compression.ZlibWrapper; +import io.netty.util.internal.*; +import io.netty.util.internal.logging.InternalLogger; +import io.netty.util.internal.logging.InternalLoggerFactory; + +import java.util.zip.CRC32; +import java.util.zip.Deflater; + +/** + * Compresses a {@link ByteBuf} using the deflate algorithm. + */ +class JdkZlibEncoder { + + private static final InternalLogger logger = InternalLoggerFactory.getInstance(JdkZlibEncoder.class); + + /** + * Maximum initial size for temporary heap buffers used for the compressed output. Buffer may still grow beyond + * this if necessary. + */ + private static final int MAX_INITIAL_OUTPUT_BUFFER_SIZE; + /** + * Max size for temporary heap buffers used to copy input data to heap. + */ + private static final int MAX_INPUT_BUFFER_SIZE; + private static final ByteBuf EMPTY_BUF; + + private final ZlibWrapper wrapper; + private final Deflater deflater; + + /* + * GZIP support + */ + private final CRC32 crc = new CRC32(); + private static final byte[] gzipHeader = {0x1f, (byte) 0x8b, Deflater.DEFLATED, 0, 0, 0, 0, 0, 0, 0}; + + static { + MAX_INITIAL_OUTPUT_BUFFER_SIZE = SystemPropertyUtil.getInt( + "io.netty.jdkzlib.encoder.maxInitialOutputBufferSize", + 65536); + MAX_INPUT_BUFFER_SIZE = SystemPropertyUtil.getInt( + "io.netty.jdkzlib.encoder.maxInputBufferSize", + 65536); + + if (logger.isDebugEnabled()) { + logger.debug("-Dio.netty.jdkzlib.encoder.maxInitialOutputBufferSize={}", MAX_INITIAL_OUTPUT_BUFFER_SIZE); + logger.debug("-Dio.netty.jdkzlib.encoder.maxInputBufferSize={}", MAX_INPUT_BUFFER_SIZE); + } + + EMPTY_BUF = allocateByteBuf(0); + } + + private static ByteBuf allocateByteBuf(int len) { + return ByteBufAllocator.DEFAULT.heapBuffer(len); + } + + private static ByteBuf allocateByteBuf() { + return ByteBufAllocator.DEFAULT.heapBuffer(); + } + + + /** + * Creates a new zlib encoder with the specified {@code compressionLevel} + * and the specified wrapper. + * + * @param compressionLevel {@code 1} yields the fastest compression and {@code 9} yields the + * best compression. {@code 0} means no compression. The default + * compression level is {@code 6}. + * @throws CompressionException if failed to initialize zlib + */ + JdkZlibEncoder(ZlibWrapper wrapper, int compressionLevel) { + ObjectUtil.checkInRange(compressionLevel, 0, 9, "compressionLevel"); + ObjectUtil.checkNotNull(wrapper, "wrapper"); + + if (wrapper == ZlibWrapper.ZLIB_OR_NONE) { + throw new IllegalArgumentException( + "wrapper '" + ZlibWrapper.ZLIB_OR_NONE + "' is not " + + "allowed for compression."); + } + + this.wrapper = wrapper; + deflater = new Deflater(compressionLevel, wrapper != ZlibWrapper.ZLIB); + } + + ByteBuf encode(byte[] in) { + if (in.length == 0) { + return EMPTY_BUF; + } + + ByteBuf out = allocateBuffer(in.length); + encodeSome(in, out); + finishEncode(out); + return out; + } + + private void encodeSome(byte[] in, ByteBuf out) { + if (wrapper == ZlibWrapper.GZIP) { + out.writeBytes(gzipHeader); + } + if (wrapper == ZlibWrapper.GZIP) { + crc.update(in, 0, in.length); + } + + deflater.setInput(in); + for (; ; ) { + deflate(out); + if (!out.isWritable()) { + out.ensureWritable(out.writerIndex()); + } else if (deflater.needsInput()) { + break; + } + } + } + + private ByteBuf allocateBuffer(int length) { + int sizeEstimate = (int) Math.ceil(length * 1.001) + 12; + switch (wrapper) { + case GZIP: + sizeEstimate += gzipHeader.length; + break; + case ZLIB: + sizeEstimate += 2; // first two magic bytes + break; + default: + throw new IllegalArgumentException(); + } + // sizeEstimate might overflow if close to 2G + if (sizeEstimate < 0 || sizeEstimate > MAX_INITIAL_OUTPUT_BUFFER_SIZE) { + // can always expand later + return allocateByteBuf(MAX_INITIAL_OUTPUT_BUFFER_SIZE); + } + return allocateByteBuf(sizeEstimate); + } + + private void finishEncode(ByteBuf out) { + ByteBuf footer = allocateByteBuf(); + deflater.finish(); + while (!deflater.finished()) { + deflate(footer); + } + if (wrapper == ZlibWrapper.GZIP) { + int crcValue = (int) crc.getValue(); + int uncBytes = deflater.getTotalIn(); + footer.writeByte(crcValue); + footer.writeByte(crcValue >>> 8); + footer.writeByte(crcValue >>> 16); + footer.writeByte(crcValue >>> 24); + footer.writeByte(uncBytes); + footer.writeByte(uncBytes >>> 8); + footer.writeByte(uncBytes >>> 16); + footer.writeByte(uncBytes >>> 24); + } + out.writeBytes(footer); + deflater.reset(); + crc.reset(); + } + + private void deflate(ByteBuf out) { + int numBytes; + do { + int writerIndex = out.writerIndex(); + numBytes = deflater.deflate( + out.array(), out.arrayOffset() + writerIndex, out.writableBytes(), Deflater.SYNC_FLUSH); + out.writerIndex(writerIndex + numBytes); + } while (numBytes > 0); + } + + void close() { + deflater.reset(); + deflater.end(); + } +} diff --git a/http/src/main/java/com/arangodb/http/compression/NoopEncoder.java b/http/src/main/java/com/arangodb/http/compression/NoopEncoder.java new file mode 100644 index 000000000..e02750166 --- /dev/null +++ b/http/src/main/java/com/arangodb/http/compression/NoopEncoder.java @@ -0,0 +1,15 @@ +package com.arangodb.http.compression; + +import io.vertx.core.buffer.Buffer; + +class NoopEncoder implements Encoder { + @Override + public Buffer encode(byte[] data) { + return Buffer.buffer(data); + } + + @Override + public String getFormat() { + return null; + } +} diff --git a/http/src/main/java/com/arangodb/http/compression/ZlibEncoder.java b/http/src/main/java/com/arangodb/http/compression/ZlibEncoder.java new file mode 100644 index 000000000..f8ad91014 --- /dev/null +++ b/http/src/main/java/com/arangodb/http/compression/ZlibEncoder.java @@ -0,0 +1,31 @@ +package com.arangodb.http.compression; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.compression.ZlibWrapper; +import io.vertx.core.buffer.Buffer; + +class ZlibEncoder implements Encoder { + private final ZlibWrapper wrapper; + private final int level; + private final String format; + + ZlibEncoder(ZlibWrapper wrapper, int level, String format) { + this.wrapper = wrapper; + this.level = level; + this.format = format; + } + + @Override + public Buffer encode(byte[] data) { + JdkZlibEncoder encoder = new JdkZlibEncoder(wrapper, level); + ByteBuf bb = encoder.encode(data); + Buffer out = Buffer.buffer(bb); + encoder.close(); + return out; + } + + @Override + public String getFormat() { + return format; + } +} From e92047a76beffc9e25108be7a4cc3f9820b81f1e Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 11 Jan 2024 19:31:00 +0100 Subject: [PATCH 04/10] CI: updates for ArangoDB 3.12 --- .github/workflows/resilience.yml | 3 +++ .github/workflows/test.yml | 8 -------- docker/start_db.sh | 7 ++++++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/resilience.yml b/.github/workflows/resilience.yml index d5b37fe42..8bca99450 100644 --- a/.github/workflows/resilience.yml +++ b/.github/workflows/resilience.yml @@ -19,6 +19,7 @@ on: jobs: test: + if: '! github.event.pull_request.draft' timeout-minutes: 20 runs-on: ubuntu-latest @@ -37,6 +38,8 @@ jobs: run: ./docker/start_db.sh env: STARTER_MODE: cluster + DOCKER_IMAGE: docker.io/arangodb-preview:devel-nightly + COMPRESSION: true - name: Info run: mvn -version - name: Start Toxiproxy diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44e1be13a..ea37961c5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,8 +38,6 @@ jobs: - single - cluster - activefailover - db-ext-names: - - false java-version: - 21 user-language: @@ -135,8 +133,6 @@ jobs: - single - cluster - activefailover - db-ext-names: - - false java-version: - 21 user-language: @@ -188,8 +184,6 @@ jobs: - docker.io/arangodb/arangodb:3.11.7 topology: - single - db-ext-names: - - false java-version: - 21 user-language: @@ -272,8 +266,6 @@ jobs: - docker.io/arangodb/enterprise:3.11.7 topology: - cluster - db-ext-names: - - false java-version: - 17 diff --git a/docker/start_db.sh b/docker/start_db.sh index b857962fd..f47ea0b57 100755 --- a/docker/start_db.sh +++ b/docker/start_db.sh @@ -12,6 +12,7 @@ STARTER_MODE=${STARTER_MODE:=single} DOCKER_IMAGE=${DOCKER_IMAGE:=docker.io/arangodb/arangodb:latest} SSL=${SSL:=false} +COMPRESSION=${COMPRESSION:=false} STARTER_DOCKER_IMAGE=docker.io/arangodb/arangodb-starter:latest GW=172.28.0.1 @@ -44,6 +45,10 @@ if [ "$SSL" == "true" ]; then ARANGOSH_SCHEME=http+ssl fi +if [ "$COMPRESSION" == "true" ]; then + STARTER_ARGS="${STARTER_ARGS} --all.http.compress-response-threshold=1" +fi + if [ "$USE_MOUNTED_DATA" == "true" ]; then STARTER_ARGS="${STARTER_ARGS} --starter.data-dir=/data" MOUNT_DATA="-v $LOCATION/data:/data" @@ -65,7 +70,7 @@ docker run -d \ --starter.address="${GW}" \ --docker.image="${DOCKER_IMAGE}" \ --starter.local --starter.mode=${STARTER_MODE} --all.log.level=debug --all.log.output=+ --log.verbose \ - --all.server.descriptors-minimum=1024 --all.javascript.allow-admin-execute=true --all.http.compress-response-threshold=1 + --all.server.descriptors-minimum=1024 --all.javascript.allow-admin-execute=true wait_server() { From 22df078877ca89326d541d70970ffefaa735c49c Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 11 Jan 2024 20:40:52 +0100 Subject: [PATCH 05/10] test compression --- .../src/test/java/resilience/ClusterTest.java | 1 + .../java/resilience/SingleServerTest.java | 1 + .../compression/CompressionTest.java | 71 +++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 resilience-tests/src/test/java/resilience/compression/CompressionTest.java diff --git a/resilience-tests/src/test/java/resilience/ClusterTest.java b/resilience-tests/src/test/java/resilience/ClusterTest.java index d16f4cbfa..7068927e1 100644 --- a/resilience-tests/src/test/java/resilience/ClusterTest.java +++ b/resilience-tests/src/test/java/resilience/ClusterTest.java @@ -52,6 +52,7 @@ static void afterAll() throws IOException { @BeforeEach void beforeEach() { enableAllEndpoints(); + logs.reset(); } protected static List getEndpoints() { diff --git a/resilience-tests/src/test/java/resilience/SingleServerTest.java b/resilience-tests/src/test/java/resilience/SingleServerTest.java index 3aa587d93..89d028469 100644 --- a/resilience-tests/src/test/java/resilience/SingleServerTest.java +++ b/resilience-tests/src/test/java/resilience/SingleServerTest.java @@ -37,6 +37,7 @@ static void afterAll() throws IOException { @BeforeEach void beforeEach() { getEndpoint().enable(); + logs.reset(); } protected static Endpoint getEndpoint() { diff --git a/resilience-tests/src/test/java/resilience/compression/CompressionTest.java b/resilience-tests/src/test/java/resilience/compression/CompressionTest.java new file mode 100644 index 000000000..77e6068e8 --- /dev/null +++ b/resilience-tests/src/test/java/resilience/compression/CompressionTest.java @@ -0,0 +1,71 @@ +package resilience.compression; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import com.arangodb.ArangoDB; +import com.arangodb.Compression; +import com.arangodb.Protocol; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import resilience.ClusterTest; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +/** + * @author Michele Rastelli + */ +class CompressionTest extends ClusterTest { + + @ParameterizedTest + @EnumSource(Protocol.class) + void gzip(Protocol protocol) { + doTest(protocol, Compression.GZIP); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + void deflate(Protocol protocol) { + doTest(protocol, Compression.DEFLATE); + } + + void doTest(Protocol protocol, Compression compression) { + assumeTrue(protocol != Protocol.VST); + assumeTrue(protocol != Protocol.HTTP_VPACK); + assumeTrue(protocol != Protocol.HTTP_JSON); + + ArangoDB adb = dbBuilder() + .protocol(protocol) + .compression(compression) + .compressionThreshold(0) + .build(); + + List data = IntStream.range(0, 500) + .mapToObj(i -> UUID.randomUUID().toString()) + .collect(Collectors.toList()); + + adb.db().query("FOR i IN @data RETURN i", String.class, + Collections.singletonMap("data", data)).asListRemaining(); + + adb.shutdown(); + + String compressionLC = compression.toString().toLowerCase(Locale.ROOT); + + // request + assertThat(logs.getLogs()) + .map(ILoggingEvent::getFormattedMessage) + .anyMatch(l -> l.contains("content-encoding: " + compressionLC) && l.contains("accept-encoding: " + compressionLC)); + + // response + assertThat(logs.getLogs()) + .map(ILoggingEvent::getFormattedMessage) + .anyMatch(l -> l.contains("content-encoding: " + compressionLC) && l.contains("server: ArangoDB")); + } + +} From e9b3503a50d21ebdcc59c05f19f00e7732edc9c4 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 12 Jan 2024 09:22:28 +0100 Subject: [PATCH 06/10] CI: fixed test docker image --- .github/workflows/resilience.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/resilience.yml b/.github/workflows/resilience.yml index 8bca99450..e190a6155 100644 --- a/.github/workflows/resilience.yml +++ b/.github/workflows/resilience.yml @@ -38,7 +38,7 @@ jobs: run: ./docker/start_db.sh env: STARTER_MODE: cluster - DOCKER_IMAGE: docker.io/arangodb-preview:devel-nightly + DOCKER_IMAGE: docker.io/arangodb/arangodb-preview:devel-nightly COMPRESSION: true - name: Info run: mvn -version From f44265b4ccfdf3a74d38b3a790b34c15d33a914a Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 15 Jan 2024 13:00:41 +0100 Subject: [PATCH 07/10] test upd --- .../test/java/resilience/compression/CompressionTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resilience-tests/src/test/java/resilience/compression/CompressionTest.java b/resilience-tests/src/test/java/resilience/compression/CompressionTest.java index 77e6068e8..14077c2d3 100644 --- a/resilience-tests/src/test/java/resilience/compression/CompressionTest.java +++ b/resilience-tests/src/test/java/resilience/compression/CompressionTest.java @@ -36,9 +36,9 @@ void deflate(Protocol protocol) { } void doTest(Protocol protocol, Compression compression) { - assumeTrue(protocol != Protocol.VST); - assumeTrue(protocol != Protocol.HTTP_VPACK); - assumeTrue(protocol != Protocol.HTTP_JSON); + assumeTrue(protocol != Protocol.VST, "VST does not support compression"); + assumeTrue(protocol != Protocol.HTTP_VPACK, "hex dumps logs"); + assumeTrue(protocol != Protocol.HTTP_JSON, "hex dumps logs"); ArangoDB adb = dbBuilder() .protocol(protocol) From a2618ce8f546fb97bfb26eab7ea1f7956d03d2cd Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 27 Feb 2024 22:03:49 +0100 Subject: [PATCH 08/10] resilience tests: disabled VST for ADB 3.12 --- .../src/test/java/resilience/ClusterTest.java | 33 +++++-- .../java/resilience/SingleServerTest.java | 28 ++++-- .../src/test/java/resilience/TestUtils.java | 98 +++++++++++++++++++ .../compression/CompressionTest.java | 18 ++-- .../connection/AcquireHostListTest.java | 3 +- .../connection/ConnectionClusterTest.java | 33 ++----- .../resilience/connection/ConnectionTest.java | 43 +++----- .../LoadBalanceNoneClusterTest.java | 7 +- .../LoadBalanceRoundRobinClusterTest.java | 7 +- .../logging/RequestLoggingTest.java | 5 +- .../retry/RetriableCursorClusterTest.java | 6 +- .../resilience/retry/RetriableCursorTest.java | 6 +- .../resilience/retry/RetryClusterTest.java | 30 ++---- .../test/java/resilience/retry/RetryTest.java | 30 ++---- .../shutdown/ShutdownClusterTest.java | 10 +- .../resilience/shutdown/ShutdownTest.java | 10 +- .../timeout/TimeoutClusterTest.java | 8 +- .../java/resilience/timeout/TimeoutTest.java | 7 +- .../vstKeepAlive/VstKeepAliveCloseTest.java | 6 +- 19 files changed, 222 insertions(+), 166 deletions(-) create mode 100644 resilience-tests/src/test/java/resilience/TestUtils.java diff --git a/resilience-tests/src/test/java/resilience/ClusterTest.java b/resilience-tests/src/test/java/resilience/ClusterTest.java index 7068927e1..78662b81e 100644 --- a/resilience-tests/src/test/java/resilience/ClusterTest.java +++ b/resilience-tests/src/test/java/resilience/ClusterTest.java @@ -2,6 +2,7 @@ import com.arangodb.ArangoDB; import com.arangodb.ArangoDBAsync; +import com.arangodb.Protocol; import com.arangodb.Request; import com.fasterxml.jackson.databind.node.ObjectNode; import eu.rekawek.toxiproxy.Proxy; @@ -10,23 +11,20 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; -import resilience.utils.MemoryAppender; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; @Tag("cluster") -public abstract class ClusterTest { +public abstract class ClusterTest extends TestUtils { - protected static final String HOST = "127.0.0.1"; - protected static final String PASSWORD = "test"; - protected static final MemoryAppender logs = new MemoryAppender(); private static final List endpoints = Arrays.asList( - new Endpoint("cluster1", HOST, 18529, "172.28.0.1:8529"), - new Endpoint("cluster2", HOST, 18539, "172.28.0.1:8539"), - new Endpoint("cluster3", HOST, 18549, "172.28.0.1:8549") + new Endpoint("cluster1", HOST, 18529, UPSTREAM_GW + ":8529"), + new Endpoint("cluster2", HOST, 18539, UPSTREAM_GW + ":8539"), + new Endpoint("cluster3", HOST, 18549, UPSTREAM_GW + ":8549") ); @BeforeAll @@ -61,12 +59,29 @@ protected static List getEndpoints() { protected static ArangoDB.Builder dbBuilder() { ArangoDB.Builder builder = new ArangoDB.Builder(); - for (Endpoint endpoint : endpoints) { + for (Endpoint endpoint : getEndpoints()) { builder.host(endpoint.getHost(), endpoint.getPort()); } return builder.password(PASSWORD); } + protected static Stream protocolProvider() { + return Stream.of(Protocol.values()) + .filter(p -> !p.equals(Protocol.VST) || isLessThanVersion(3, 12)); + } + + protected static Stream builderProvider() { + return protocolProvider().map(p -> dbBuilder().protocol(p)); + } + + protected static Stream adbProvider() { + return builderProvider().map(ArangoDB.Builder::build); + } + + protected static Stream asyncAdbProvider() { + return adbProvider().map(ArangoDB::async); + } + protected static String serverIdGET(ArangoDB adb) { return adb.execute(Request.builder() .method(Request.Method.GET) diff --git a/resilience-tests/src/test/java/resilience/SingleServerTest.java b/resilience-tests/src/test/java/resilience/SingleServerTest.java index 89d028469..40bddbef9 100644 --- a/resilience-tests/src/test/java/resilience/SingleServerTest.java +++ b/resilience-tests/src/test/java/resilience/SingleServerTest.java @@ -1,7 +1,8 @@ package resilience; import com.arangodb.ArangoDB; -import resilience.utils.MemoryAppender; +import com.arangodb.ArangoDBAsync; +import com.arangodb.Protocol; import eu.rekawek.toxiproxy.Proxy; import eu.rekawek.toxiproxy.ToxiproxyClient; import org.junit.jupiter.api.AfterAll; @@ -10,14 +11,12 @@ import org.junit.jupiter.api.Tag; import java.io.IOException; +import java.util.stream.Stream; @Tag("singleServer") -public abstract class SingleServerTest { +public abstract class SingleServerTest extends TestUtils { - protected static final String HOST = "127.0.0.1"; - protected static final String PASSWORD = "test"; - protected static final MemoryAppender logs = new MemoryAppender(); - private static final Endpoint endpoint = new Endpoint("singleServer", HOST, 18529, "172.28.0.1:8529"); + private static final Endpoint endpoint = new Endpoint("singleServer", HOST, 18529, UPSTREAM_GW + ":8529"); @BeforeAll static void beforeAll() throws IOException { @@ -50,4 +49,21 @@ protected static ArangoDB.Builder dbBuilder() { .password(PASSWORD); } + protected static Stream protocolProvider() { + return Stream.of(Protocol.values()) + .filter(p -> !p.equals(Protocol.VST) || isLessThanVersion(3, 12)); + } + + protected static Stream builderProvider() { + return protocolProvider().map(p -> dbBuilder().protocol(p)); + } + + protected static Stream adbProvider() { + return builderProvider().map(ArangoDB.Builder::build); + } + + protected static Stream asyncAdbProvider() { + return adbProvider().map(ArangoDB::async); + } + } diff --git a/resilience-tests/src/test/java/resilience/TestUtils.java b/resilience-tests/src/test/java/resilience/TestUtils.java new file mode 100644 index 000000000..e9e4d3aff --- /dev/null +++ b/resilience-tests/src/test/java/resilience/TestUtils.java @@ -0,0 +1,98 @@ +/* + * DISCLAIMER + * + * Copyright 2016 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package resilience; + + +import com.arangodb.ArangoDB; +import com.arangodb.entity.ArangoDBVersion; +import resilience.utils.MemoryAppender; + +/** + * @author Michele Rastelli + */ +public abstract class TestUtils { + + protected static final String HOST = "127.0.0.1"; + protected static final String UPSTREAM_GW = "172.28.0.1"; + protected static final String PASSWORD = "test"; + protected static final MemoryAppender logs = new MemoryAppender(); + private static final ArangoDBVersion version = new ArangoDB.Builder() + .host(UPSTREAM_GW, 8529) + .password(PASSWORD) + .build() + .getVersion(); + + protected static boolean isAtLeastVersion(final int major, final int minor) { + return isAtLeastVersion(major, minor, 0); + } + + protected static boolean isAtLeastVersion(final int major, final int minor, final int patch) { + return isAtLeastVersion(version.getVersion(), major, minor, patch); + } + + protected static boolean isLessThanVersion(final int major, final int minor) { + return isLessThanVersion(major, minor, 0); + } + + protected static boolean isLessThanVersion(final int major, final int minor, final int patch) { + return isLessThanVersion(version.getVersion(), major, minor, patch); + } + + /** + * Parses {@param version} and checks whether it is greater or equal to <{@param otherMajor}, {@param otherMinor}, + * {@param otherPatch}> comparing the corresponding version components in lexicographical order. + */ + private static boolean isAtLeastVersion(final String version, final int otherMajor, final int otherMinor, + final int otherPatch) { + return compareVersion(version, otherMajor, otherMinor, otherPatch) >= 0; + } + + /** + * Parses {@param version} and checks whether it is less than <{@param otherMajor}, {@param otherMinor}, + * {@param otherPatch}> comparing the corresponding version components in lexicographical order. + */ + private static boolean isLessThanVersion(final String version, final int otherMajor, final int otherMinor, + final int otherPatch) { + return compareVersion(version, otherMajor, otherMinor, otherPatch) < 0; + } + + private static int compareVersion(final String version, final int otherMajor, final int otherMinor, + final int otherPatch) { + String[] parts = version.split("-")[0].split("\\."); + + int major = Integer.parseInt(parts[0]); + int minor = Integer.parseInt(parts[1]); + int patch = Integer.parseInt(parts[2]); + + int majorComparison = Integer.compare(major, otherMajor); + if (majorComparison != 0) { + return majorComparison; + } + + int minorComparison = Integer.compare(minor, otherMinor); + if (minorComparison != 0) { + return minorComparison; + } + + return Integer.compare(patch, otherPatch); + } + +} diff --git a/resilience-tests/src/test/java/resilience/compression/CompressionTest.java b/resilience-tests/src/test/java/resilience/compression/CompressionTest.java index 14077c2d3..5c04d058a 100644 --- a/resilience-tests/src/test/java/resilience/compression/CompressionTest.java +++ b/resilience-tests/src/test/java/resilience/compression/CompressionTest.java @@ -5,7 +5,7 @@ import com.arangodb.Compression; import com.arangodb.Protocol; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import resilience.ClusterTest; import java.util.Collections; @@ -24,21 +24,27 @@ class CompressionTest extends ClusterTest { @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void gzip(Protocol protocol) { doTest(protocol, Compression.GZIP); } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void deflate(Protocol protocol) { doTest(protocol, Compression.DEFLATE); } void doTest(Protocol protocol, Compression compression) { - assumeTrue(protocol != Protocol.VST, "VST does not support compression"); - assumeTrue(protocol != Protocol.HTTP_VPACK, "hex dumps logs"); - assumeTrue(protocol != Protocol.HTTP_JSON, "hex dumps logs"); + assumeTrue(isAtLeastVersion(3, 12)); + assumeTrue(protocol != Protocol.VST); + + assumeTrue(protocol != Protocol.HTTP_VPACK, "hex dumps logs"); // FIXME + assumeTrue(protocol != Protocol.HTTP_JSON, "hex dumps logs"); // FIXME + + // FIXME: + // When using HTTP_VPACK or HTTP_JSON, the logs are hex dumps. + // Implement a way to check the content-encoding and accept-encoding headers from these logs. ArangoDB adb = dbBuilder() .protocol(protocol) diff --git a/resilience-tests/src/test/java/resilience/connection/AcquireHostListTest.java b/resilience-tests/src/test/java/resilience/connection/AcquireHostListTest.java index 92e2fc10e..32faa7b5b 100644 --- a/resilience-tests/src/test/java/resilience/connection/AcquireHostListTest.java +++ b/resilience-tests/src/test/java/resilience/connection/AcquireHostListTest.java @@ -5,6 +5,7 @@ import com.arangodb.entity.LoadBalancingStrategy; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import resilience.ClusterTest; import resilience.Endpoint; @@ -17,7 +18,7 @@ public class AcquireHostListTest extends ClusterTest { @ParameterizedTest(name = "{index}") - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void acquireHostList(Protocol protocol) { ArangoDB adb = new ArangoDB.Builder() .host("127.0.0.1", 8529) diff --git a/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java b/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java index 35f54e855..1b18a555d 100644 --- a/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java +++ b/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java @@ -9,7 +9,6 @@ import java.net.ConnectException; import java.net.UnknownHostException; import java.util.concurrent.ExecutionException; -import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -19,26 +18,6 @@ */ class ConnectionClusterTest extends ClusterTest { - static Stream protocolProvider() { - return Stream.of( - Protocol.VST, - Protocol.HTTP_VPACK, - Protocol.HTTP2_VPACK - ); - } - - static Stream arangoProvider() { - return Stream.of( - dbBuilder().protocol(Protocol.VST).build(), - dbBuilder().protocol(Protocol.HTTP_VPACK).build(), - dbBuilder().protocol(Protocol.HTTP2_JSON).build() - ); - } - - static Stream asyncArangoProvider() { - return arangoProvider().map(ArangoDB::async); - } - @ParameterizedTest @MethodSource("protocolProvider") void nameResolutionFail(Protocol protocol) { @@ -120,7 +99,7 @@ void nameResolutionFailoverAsync(Protocol protocol) throws ExecutionException, I } @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void connectionFail(ArangoDB arangoDB) { disableAllEndpoints(); @@ -137,7 +116,7 @@ void connectionFail(ArangoDB arangoDB) { } @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void connectionFailAsync(ArangoDBAsync arangoDB) { disableAllEndpoints(); @@ -153,7 +132,7 @@ void connectionFailAsync(ArangoDBAsync arangoDB) { } @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void connectionFailover(ArangoDB arangoDB) { getEndpoints().get(0).disableNow(); getEndpoints().get(1).disableNow(); @@ -169,7 +148,7 @@ void connectionFailover(ArangoDB arangoDB) { } @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void connectionFailoverAsync(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { getEndpoints().get(0).disableNow(); getEndpoints().get(1).disableNow(); @@ -185,7 +164,7 @@ void connectionFailoverAsync(ArangoDBAsync arangoDB) throws ExecutionException, } @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void connectionFailoverPost(ArangoDB arangoDB) { getEndpoints().get(0).disableNow(); getEndpoints().get(1).disableNow(); @@ -201,7 +180,7 @@ void connectionFailoverPost(ArangoDB arangoDB) { } @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void connectionFailoverPostAsync(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { getEndpoints().get(0).disableNow(); getEndpoints().get(1).disableNow(); diff --git a/resilience-tests/src/test/java/resilience/connection/ConnectionTest.java b/resilience-tests/src/test/java/resilience/connection/ConnectionTest.java index ee86998db..b64f1dd42 100644 --- a/resilience-tests/src/test/java/resilience/connection/ConnectionTest.java +++ b/resilience-tests/src/test/java/resilience/connection/ConnectionTest.java @@ -3,15 +3,14 @@ import com.arangodb.*; import eu.rekawek.toxiproxy.model.ToxicDirection; import eu.rekawek.toxiproxy.model.toxic.ResetPeer; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; import resilience.SingleServerTest; import java.io.IOException; import java.net.ConnectException; import java.net.UnknownHostException; -import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -22,29 +21,11 @@ */ class ConnectionTest extends SingleServerTest { - static Stream protocolProvider() { - return Stream.of( - Protocol.VST, - Protocol.HTTP_VPACK, - Protocol.HTTP2_VPACK - ); - } - - static Stream arangoProvider() { - return Stream.of( - dbBuilder().protocol(Protocol.VST).build(), - dbBuilder().protocol(Protocol.HTTP_VPACK).build(), - dbBuilder().protocol(Protocol.HTTP2_VPACK).build() - ); - } - - static Stream asyncArangoProvider() { - return arangoProvider().map(ArangoDB::async); - } - @ParameterizedTest @MethodSource("protocolProvider") + @Disabled void nameResolutionFail(Protocol protocol) { + // FIXME: make this test faster and re-enable ArangoDB arangoDB = new ArangoDB.Builder() .host("wrongHost", 8529) .protocol(protocol) @@ -64,7 +45,9 @@ void nameResolutionFail(Protocol protocol) { @ParameterizedTest @MethodSource("protocolProvider") + @Disabled void nameResolutionFailAsync(Protocol protocol) { + // FIXME: make this test faster and re-enable ArangoDBAsync arangoDB = new ArangoDB.Builder() .host("wrongHost", 8529) .protocol(protocol) @@ -84,7 +67,7 @@ void nameResolutionFailAsync(Protocol protocol) { } @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void connectionFail(ArangoDB arangoDB) { getEndpoint().disableNow(); Throwable thrown = catchThrowable(arangoDB::getVersion); @@ -99,7 +82,7 @@ void connectionFail(ArangoDB arangoDB) { } @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void connectionFailAsync(ArangoDBAsync arangoDB) { getEndpoint().disableNow(); @@ -115,7 +98,7 @@ void connectionFailAsync(ArangoDBAsync arangoDB) { } @ParameterizedTest(name = "{index}") - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void authFail(Protocol protocol) { ArangoDB adb = new ArangoDB.Builder() .host(getEndpoint().getHost(), getEndpoint().getPort()) @@ -131,7 +114,7 @@ void authFail(Protocol protocol) { } @ParameterizedTest(name = "{index}") - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void authFailAsync(Protocol protocol) { ArangoDBAsync adb = new ArangoDB.Builder() .host(getEndpoint().getHost(), getEndpoint().getPort()) @@ -148,7 +131,7 @@ void authFailAsync(Protocol protocol) { } @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void connClose(ArangoDB adb) { getEndpoint().disable(500); Throwable thrown = catchThrowable(() -> adb.db().query("RETURN SLEEP(1)", Void.class)); @@ -158,7 +141,7 @@ void connClose(ArangoDB adb) { } @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void connCloseAsync(ArangoDBAsync adb) { getEndpoint().disable(500); Throwable thrown = catchThrowable(() -> adb.db().query("RETURN SLEEP(1)", Void.class).get()).getCause(); @@ -168,7 +151,7 @@ void connCloseAsync(ArangoDBAsync adb) { } @ParameterizedTest(name = "{index}") - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void connReset(Protocol protocol) throws IOException, InterruptedException { assumeTrue(!protocol.equals(Protocol.VST), "DE-776"); // FIXME ArangoDB adb = new ArangoDB.Builder() @@ -188,7 +171,7 @@ void connReset(Protocol protocol) throws IOException, InterruptedException { } @ParameterizedTest(name = "{index}") - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void connResetAsync(Protocol protocol) throws IOException, InterruptedException { assumeTrue(!protocol.equals(Protocol.VST), "DE-776"); // FIXME ArangoDBAsync adb = new ArangoDB.Builder() diff --git a/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceNoneClusterTest.java b/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceNoneClusterTest.java index 421d65aa4..d225ed328 100644 --- a/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceNoneClusterTest.java +++ b/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceNoneClusterTest.java @@ -3,7 +3,6 @@ import com.arangodb.ArangoDB; import com.arangodb.ArangoDBAsync; import com.arangodb.ArangoDBException; -import com.arangodb.Protocol; import com.arangodb.entity.LoadBalancingStrategy; import eu.rekawek.toxiproxy.model.ToxicDirection; import eu.rekawek.toxiproxy.model.toxic.Latency; @@ -22,11 +21,7 @@ public class LoadBalanceNoneClusterTest extends ClusterTest { static Stream arangoProvider() { - return Stream.of( - dbBuilder().loadBalancingStrategy(LoadBalancingStrategy.NONE).protocol(Protocol.VST).build(), - dbBuilder().loadBalancingStrategy(LoadBalancingStrategy.NONE).protocol(Protocol.HTTP_VPACK).build(), - dbBuilder().loadBalancingStrategy(LoadBalancingStrategy.NONE).protocol(Protocol.HTTP2_JSON).build() - ); + return builderProvider().map(it->it.loadBalancingStrategy(LoadBalancingStrategy.NONE).build()); } static Stream asyncArangoProvider() { diff --git a/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceRoundRobinClusterTest.java b/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceRoundRobinClusterTest.java index 3a7123f5a..1efb0305d 100644 --- a/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceRoundRobinClusterTest.java +++ b/resilience-tests/src/test/java/resilience/loadbalance/LoadBalanceRoundRobinClusterTest.java @@ -3,7 +3,6 @@ import com.arangodb.ArangoDB; import com.arangodb.ArangoDBAsync; import com.arangodb.ArangoDBException; -import com.arangodb.Protocol; import com.arangodb.entity.LoadBalancingStrategy; import eu.rekawek.toxiproxy.model.ToxicDirection; import eu.rekawek.toxiproxy.model.toxic.Latency; @@ -23,11 +22,7 @@ public class LoadBalanceRoundRobinClusterTest extends ClusterTest { static Stream arangoProvider() { - return Stream.of( - dbBuilder().loadBalancingStrategy(LoadBalancingStrategy.ROUND_ROBIN).protocol(Protocol.VST).build(), - dbBuilder().loadBalancingStrategy(LoadBalancingStrategy.ROUND_ROBIN).protocol(Protocol.HTTP_VPACK).build(), - dbBuilder().loadBalancingStrategy(LoadBalancingStrategy.ROUND_ROBIN).protocol(Protocol.HTTP2_JSON).build() - ); + return builderProvider().map(it -> it.loadBalancingStrategy(LoadBalancingStrategy.ROUND_ROBIN).build()); } static Stream asyncArangoProvider() { diff --git a/resilience-tests/src/test/java/resilience/logging/RequestLoggingTest.java b/resilience-tests/src/test/java/resilience/logging/RequestLoggingTest.java index 16f327292..42ff429b9 100644 --- a/resilience-tests/src/test/java/resilience/logging/RequestLoggingTest.java +++ b/resilience-tests/src/test/java/resilience/logging/RequestLoggingTest.java @@ -6,19 +6,20 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import resilience.SingleServerTest; import java.util.Collections; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class RequestLoggingTest extends SingleServerTest { private final static ObjectMapper mapper = new ObjectMapper(); @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void requestLogging(Protocol protocol) { ArangoDB adb = new ArangoDB.Builder() .host("172.28.0.1", 8529) diff --git a/resilience-tests/src/test/java/resilience/retry/RetriableCursorClusterTest.java b/resilience-tests/src/test/java/resilience/retry/RetriableCursorClusterTest.java index 45f44d629..c9802933c 100644 --- a/resilience-tests/src/test/java/resilience/retry/RetriableCursorClusterTest.java +++ b/resilience-tests/src/test/java/resilience/retry/RetriableCursorClusterTest.java @@ -21,11 +21,7 @@ class RetriableCursorClusterTest extends ClusterTest { static Stream arangoProvider() { - return Stream.of( - dbBuilder().timeout(1_000).protocol(Protocol.VST).build(), - dbBuilder().timeout(1_000).protocol(Protocol.HTTP_JSON).build(), - dbBuilder().timeout(1_000).protocol(Protocol.HTTP_VPACK).build() - ); + return builderProvider().map(it -> it.timeout(1_000).build()); } static Stream asyncArangoProvider() { diff --git a/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java b/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java index 7594ae548..b57737a8f 100644 --- a/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java +++ b/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java @@ -22,11 +22,7 @@ class RetriableCursorTest extends SingleServerTest { static Stream arangoProvider() { - return Stream.of( - dbBuilder().timeout(1_000).protocol(Protocol.VST).build(), - dbBuilder().timeout(1_000).protocol(Protocol.HTTP_JSON).build(), - dbBuilder().timeout(1_000).protocol(Protocol.HTTP_VPACK).build() - ); + return builderProvider().map(it -> it.timeout(1_000).build()); } static Stream asyncArangoProvider() { diff --git a/resilience-tests/src/test/java/resilience/retry/RetryClusterTest.java b/resilience-tests/src/test/java/resilience/retry/RetryClusterTest.java index 8dff57235..d2f44eba2 100644 --- a/resilience-tests/src/test/java/resilience/retry/RetryClusterTest.java +++ b/resilience-tests/src/test/java/resilience/retry/RetryClusterTest.java @@ -6,14 +6,12 @@ import eu.rekawek.toxiproxy.model.toxic.Latency; import io.vertx.core.http.HttpClosedException; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; import resilience.ClusterTest; import java.io.IOException; import java.net.ConnectException; import java.util.concurrent.*; -import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -24,18 +22,6 @@ */ class RetryClusterTest extends ClusterTest { - static Stream arangoProvider() { - return Stream.of( - dbBuilder().protocol(Protocol.VST).build(), - dbBuilder().protocol(Protocol.HTTP_VPACK).build(), - dbBuilder().protocol(Protocol.HTTP2_VPACK).build() - ); - } - - static Stream asyncArangoProvider() { - return arangoProvider().map(ArangoDB::async); - } - /** * on reconnection failure: - 3x logs WARN Could not connect to host[addr=127.0.0.1,port=8529] - * ArangoDBException("Cannot contact any host") @@ -43,7 +29,7 @@ static Stream asyncArangoProvider() { * once the proxy is re-enabled: - the subsequent requests should be successful */ @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void unreachableHost(ArangoDB arangoDB) { arangoDB.getVersion(); disableAllEndpoints(); @@ -76,7 +62,7 @@ void unreachableHost(ArangoDB arangoDB) { * once the proxy is re-enabled: - the subsequent requests should be successful */ @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void unreachableHostAsync(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { arangoDB.getVersion().get(); disableAllEndpoints(); @@ -103,7 +89,7 @@ void unreachableHostAsync(ArangoDBAsync arangoDB) throws ExecutionException, Int } @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void unreachableHostFailover(ArangoDB arangoDB) { arangoDB.getVersion(); getEndpoints().get(0).disableNow(); @@ -120,7 +106,7 @@ void unreachableHostFailover(ArangoDB arangoDB) { } @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void unreachableHostFailoverAsync(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { arangoDB.getVersion().get(); getEndpoints().get(0).disableNow(); @@ -138,7 +124,7 @@ void unreachableHostFailoverAsync(ArangoDBAsync arangoDB) throws ExecutionExcept @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void retryGetOnClosedConnection(Protocol protocol) throws IOException, InterruptedException { assumeTrue(protocol != Protocol.VST); ArangoDB arangoDB = dbBuilder() @@ -164,7 +150,7 @@ void retryGetOnClosedConnection(Protocol protocol) throws IOException, Interrupt } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void retryGetOnClosedConnectionAsync(Protocol protocol) throws IOException, InterruptedException, ExecutionException { assumeTrue(protocol != Protocol.VST); ArangoDBAsync arangoDB = dbBuilder() @@ -197,7 +183,7 @@ void retryGetOnClosedConnectionAsync(Protocol protocol) throws IOException, Inte * the subsequent requests should fail over to a different coordinator and be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void notRetryPostOnClosedConnection(Protocol protocol) throws IOException, InterruptedException { ArangoDB arangoDB = dbBuilder() .protocol(protocol) @@ -230,7 +216,7 @@ void notRetryPostOnClosedConnection(Protocol protocol) throws IOException, Inter * the subsequent requests should fail over to a different coordinator and be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void notRetryPostOnClosedConnectionAsync(Protocol protocol) throws IOException, InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() .protocol(protocol) diff --git a/resilience-tests/src/test/java/resilience/retry/RetryTest.java b/resilience-tests/src/test/java/resilience/retry/RetryTest.java index 1aee5d704..704a07e88 100644 --- a/resilience-tests/src/test/java/resilience/retry/RetryTest.java +++ b/resilience-tests/src/test/java/resilience/retry/RetryTest.java @@ -3,7 +3,6 @@ import ch.qos.logback.classic.Level; import com.arangodb.*; import io.vertx.core.http.HttpClosedException; -import org.junit.jupiter.params.provider.EnumSource; import resilience.SingleServerTest; import eu.rekawek.toxiproxy.model.ToxicDirection; import eu.rekawek.toxiproxy.model.toxic.Latency; @@ -14,7 +13,6 @@ import java.net.ConnectException; import java.util.List; import java.util.concurrent.*; -import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -25,18 +23,6 @@ */ class RetryTest extends SingleServerTest { - static Stream arangoProvider() { - return Stream.of( - dbBuilder().protocol(Protocol.VST).build(), - dbBuilder().protocol(Protocol.HTTP_VPACK).build(), - dbBuilder().protocol(Protocol.HTTP2_VPACK).build() - ); - } - - static Stream asyncArangoProvider() { - return arangoProvider().map(ArangoDB::async); - } - /** * on reconnection failure: - 3x logs WARN Could not connect to host[addr=127.0.0.1,port=8529] - * ArangoDBException("Cannot contact any host") @@ -44,7 +30,7 @@ static Stream asyncArangoProvider() { * once the proxy is re-enabled: - the subsequent requests should be successful */ @ParameterizedTest(name = "{index}") - @MethodSource("arangoProvider") + @MethodSource("adbProvider") void unreachableHost(ArangoDB arangoDB) { arangoDB.getVersion(); getEndpoint().disableNow(); @@ -77,7 +63,7 @@ void unreachableHost(ArangoDB arangoDB) { * once the proxy is re-enabled: - the subsequent requests should be successful */ @ParameterizedTest(name = "{index}") - @MethodSource("asyncArangoProvider") + @MethodSource("asyncAdbProvider") void unreachableHostAsync(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { arangoDB.getVersion().get(); getEndpoint().disableNow(); @@ -111,7 +97,7 @@ void unreachableHostAsync(ArangoDBAsync arangoDB) throws ExecutionException, Int * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void connectionTimeout(Protocol protocol) throws IOException, InterruptedException { ArangoDB arangoDB = dbBuilder() .timeout(1_000) @@ -145,7 +131,7 @@ void connectionTimeout(Protocol protocol) throws IOException, InterruptedExcepti * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void connectionTimeoutAsync(Protocol protocol) throws IOException, InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() .timeout(1_000) @@ -184,7 +170,7 @@ void connectionTimeoutAsync(Protocol protocol) throws IOException, InterruptedEx * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void retryGetOnClosedConnection(Protocol protocol) throws IOException, InterruptedException { assumeTrue(protocol != Protocol.VST); ArangoDB arangoDB = dbBuilder() @@ -226,7 +212,7 @@ void retryGetOnClosedConnection(Protocol protocol) throws IOException, Interrupt * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void retryGetOnClosedConnectionAsync(Protocol protocol) throws IOException, InterruptedException, ExecutionException { assumeTrue(protocol != Protocol.VST); ArangoDBAsync arangoDB = dbBuilder() @@ -265,7 +251,7 @@ void retryGetOnClosedConnectionAsync(Protocol protocol) throws IOException, Inte * once restored: - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void notRetryPostOnClosedConnection(Protocol protocol) throws IOException, InterruptedException { ArangoDB arangoDB = dbBuilder() .protocol(protocol) @@ -298,7 +284,7 @@ void notRetryPostOnClosedConnection(Protocol protocol) throws IOException, Inter * once restored: - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void notRetryPostOnClosedConnectionAsync(Protocol protocol) throws IOException, InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() .protocol(protocol) diff --git a/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java b/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java index ca8f6ba36..b55cbfaee 100644 --- a/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java +++ b/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java @@ -6,7 +6,7 @@ import com.arangodb.Protocol; import io.vertx.core.http.HttpClosedException; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import resilience.ClusterTest; import java.io.IOException; @@ -25,7 +25,7 @@ class ShutdownClusterTest extends ClusterTest { @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdown(Protocol protocol) throws InterruptedException { ArangoDB arangoDB = dbBuilder() .protocol(protocol) @@ -40,7 +40,7 @@ void shutdown(Protocol protocol) throws InterruptedException { } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdownAsync(Protocol protocol) throws InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() .protocol(protocol) @@ -56,7 +56,7 @@ void shutdownAsync(Protocol protocol) throws InterruptedException, ExecutionExce } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdownWithPendingRequests(Protocol protocol) { assumeTrue(protocol != Protocol.VST); ArangoDB arangoDB = dbBuilder() @@ -73,7 +73,7 @@ void shutdownWithPendingRequests(Protocol protocol) { } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdownWithPendingRequestsAsync(Protocol protocol) { assumeTrue(protocol != Protocol.VST); ArangoDBAsync arangoDB = dbBuilder() diff --git a/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java b/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java index 944cc94b1..107710d7f 100644 --- a/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java +++ b/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java @@ -6,7 +6,7 @@ import com.arangodb.Protocol; import io.vertx.core.http.HttpClosedException; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import resilience.SingleServerTest; import java.io.IOException; @@ -25,7 +25,7 @@ class ShutdownTest extends SingleServerTest { @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdown(Protocol protocol) throws InterruptedException { ArangoDB arangoDB = dbBuilder() .protocol(protocol) @@ -40,7 +40,7 @@ void shutdown(Protocol protocol) throws InterruptedException { } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdownAsync(Protocol protocol) throws InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() .protocol(protocol) @@ -56,7 +56,7 @@ void shutdownAsync(Protocol protocol) throws InterruptedException, ExecutionExce } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdownWithPendingRequests(Protocol protocol) { assumeTrue(protocol != Protocol.VST); ArangoDB arangoDB = dbBuilder() @@ -73,7 +73,7 @@ void shutdownWithPendingRequests(Protocol protocol) { } @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void shutdownWithPendingRequestsAsync(Protocol protocol) { assumeTrue(protocol != Protocol.VST); ArangoDBAsync arangoDB = dbBuilder() diff --git a/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java b/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java index fc7bf15f7..5f13cf040 100644 --- a/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java +++ b/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java @@ -2,9 +2,8 @@ import com.arangodb.*; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import resilience.ClusterTest; -import resilience.SingleServerTest; import java.util.Collections; import java.util.Map; @@ -13,7 +12,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; -import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * @author Michele Rastelli @@ -29,7 +27,7 @@ class TimeoutClusterTest extends ClusterTest { * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void requestTimeout(Protocol protocol) throws InterruptedException { ArangoDB arangoDB = dbBuilder() .timeout(1_000) @@ -70,7 +68,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void requestTimeoutAsync(Protocol protocol) throws InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() .timeout(1_000) diff --git a/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java b/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java index 3a45109a3..24882f0bc 100644 --- a/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java +++ b/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java @@ -2,7 +2,7 @@ import com.arangodb.*; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import resilience.SingleServerTest; import java.util.Collections; @@ -12,6 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; +import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * @author Michele Rastelli @@ -27,7 +28,7 @@ class TimeoutTest extends SingleServerTest { * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void requestTimeout(Protocol protocol) throws InterruptedException { ArangoDB arangoDB = dbBuilder() .timeout(1_000) @@ -68,7 +69,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { * - the subsequent requests should be successful */ @ParameterizedTest - @EnumSource(Protocol.class) + @MethodSource("protocolProvider") void requestTimeoutAsync(Protocol protocol) throws InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() .timeout(1_000) diff --git a/resilience-tests/src/test/java/resilience/vstKeepAlive/VstKeepAliveCloseTest.java b/resilience-tests/src/test/java/resilience/vstKeepAlive/VstKeepAliveCloseTest.java index 533be6d8a..b9b590547 100644 --- a/resilience-tests/src/test/java/resilience/vstKeepAlive/VstKeepAliveCloseTest.java +++ b/resilience-tests/src/test/java/resilience/vstKeepAlive/VstKeepAliveCloseTest.java @@ -15,6 +15,7 @@ import java.util.concurrent.ExecutionException; import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * @author Michele Rastelli @@ -25,6 +26,7 @@ class VstKeepAliveCloseTest extends SingleServerTest { @BeforeEach void init() { + assumeTrue(isLessThanVersion(3, 12)); arangoDB = dbBuilder() .protocol(Protocol.VST) .timeout(1000) @@ -34,7 +36,9 @@ void init() { @AfterEach void shutDown() { - arangoDB.shutdown(); + if (arangoDB != null) { + arangoDB.shutdown(); + } } /** From ec904854e96309936fa3e3ad0f42bd897030fd3f Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 27 Feb 2024 22:22:30 +0100 Subject: [PATCH 09/10] faster resilience tests --- .../resilience/connection/ConnectionClusterTest.java | 9 +++++++++ .../java/resilience/retry/RetriableCursorTest.java | 2 +- .../src/test/java/resilience/retry/RetryTest.java | 4 ++-- .../resilience/shutdown/ShutdownClusterTest.java | 4 ++-- .../test/java/resilience/shutdown/ShutdownTest.java | 4 ++-- .../java/resilience/timeout/TimeoutClusterTest.java | 12 ++++++------ .../test/java/resilience/timeout/TimeoutTest.java | 12 ++++++------ 7 files changed, 28 insertions(+), 19 deletions(-) diff --git a/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java b/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java index 1b18a555d..3748ea975 100644 --- a/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java +++ b/resilience-tests/src/test/java/resilience/connection/ConnectionClusterTest.java @@ -2,6 +2,7 @@ import ch.qos.logback.classic.Level; import com.arangodb.*; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import resilience.ClusterTest; @@ -20,7 +21,9 @@ class ConnectionClusterTest extends ClusterTest { @ParameterizedTest @MethodSource("protocolProvider") + @Disabled void nameResolutionFail(Protocol protocol) { + // FIXME: make this test faster and re-enable ArangoDB arangoDB = new ArangoDB.Builder() .host("wrongHost", 8529) .protocol(protocol) @@ -40,7 +43,9 @@ void nameResolutionFail(Protocol protocol) { @ParameterizedTest @MethodSource("protocolProvider") + @Disabled void nameResolutionFailAsync(Protocol protocol) { + // FIXME: make this test faster and re-enable ArangoDBAsync arangoDB = new ArangoDB.Builder() .host("wrongHost", 8529) .protocol(protocol) @@ -61,7 +66,9 @@ void nameResolutionFailAsync(Protocol protocol) { @ParameterizedTest @MethodSource("protocolProvider") + @Disabled void nameResolutionFailover(Protocol protocol) { + // FIXME: make this test faster and re-enable ArangoDB arangoDB = new ArangoDB.Builder() .password("test") .host("wrongHost", 8529) @@ -80,7 +87,9 @@ void nameResolutionFailover(Protocol protocol) { @ParameterizedTest @MethodSource("protocolProvider") + @Disabled void nameResolutionFailoverAsync(Protocol protocol) throws ExecutionException, InterruptedException { + // FIXME: make this test faster and re-enable ArangoDBAsync arangoDB = new ArangoDB.Builder() .password("test") .host("wrongHost", 8529) diff --git a/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java b/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java index b57737a8f..b440e8155 100644 --- a/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java +++ b/resilience-tests/src/test/java/resilience/retry/RetriableCursorTest.java @@ -22,7 +22,7 @@ class RetriableCursorTest extends SingleServerTest { static Stream arangoProvider() { - return builderProvider().map(it -> it.timeout(1_000).build()); + return builderProvider().map(it -> it.timeout(500).build()); } static Stream asyncArangoProvider() { diff --git a/resilience-tests/src/test/java/resilience/retry/RetryTest.java b/resilience-tests/src/test/java/resilience/retry/RetryTest.java index 704a07e88..81875c4aa 100644 --- a/resilience-tests/src/test/java/resilience/retry/RetryTest.java +++ b/resilience-tests/src/test/java/resilience/retry/RetryTest.java @@ -100,7 +100,7 @@ void unreachableHostAsync(ArangoDBAsync arangoDB) throws ExecutionException, Int @MethodSource("protocolProvider") void connectionTimeout(Protocol protocol) throws IOException, InterruptedException { ArangoDB arangoDB = dbBuilder() - .timeout(1_000) + .timeout(500) .protocol(protocol) .build(); @@ -134,7 +134,7 @@ void connectionTimeout(Protocol protocol) throws IOException, InterruptedExcepti @MethodSource("protocolProvider") void connectionTimeoutAsync(Protocol protocol) throws IOException, InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() - .timeout(1_000) + .timeout(500) .protocol(protocol) .build() .async(); diff --git a/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java b/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java index b55cbfaee..0ff83e7c6 100644 --- a/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java +++ b/resilience-tests/src/test/java/resilience/shutdown/ShutdownClusterTest.java @@ -33,7 +33,7 @@ void shutdown(Protocol protocol) throws InterruptedException { arangoDB.getVersion(); arangoDB.shutdown(); - Thread.sleep(1_000); + Thread.sleep(500); Throwable thrown = catchThrowable(arangoDB::getVersion); assertThat(thrown).isInstanceOf(ArangoDBException.class); assertThat(thrown.getMessage()).contains("closed"); @@ -49,7 +49,7 @@ void shutdownAsync(Protocol protocol) throws InterruptedException, ExecutionExce arangoDB.getVersion().get(); arangoDB.shutdown(); - Thread.sleep(1_000); + Thread.sleep(500); Throwable thrown = catchThrowable(() -> arangoDB.getVersion().get()).getCause(); assertThat(thrown).isInstanceOf(ArangoDBException.class); assertThat(thrown.getMessage()).contains("closed"); diff --git a/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java b/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java index 107710d7f..4132f6036 100644 --- a/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java +++ b/resilience-tests/src/test/java/resilience/shutdown/ShutdownTest.java @@ -33,7 +33,7 @@ void shutdown(Protocol protocol) throws InterruptedException { arangoDB.getVersion(); arangoDB.shutdown(); - Thread.sleep(1_000); + Thread.sleep(500); Throwable thrown = catchThrowable(arangoDB::getVersion); assertThat(thrown).isInstanceOf(ArangoDBException.class); assertThat(thrown.getMessage()).contains("closed"); @@ -49,7 +49,7 @@ void shutdownAsync(Protocol protocol) throws InterruptedException, ExecutionExce arangoDB.getVersion().get(); arangoDB.shutdown(); - Thread.sleep(1_000); + Thread.sleep(500); Throwable thrown = catchThrowable(() -> arangoDB.getVersion().get()).getCause(); assertThat(thrown).isInstanceOf(ArangoDBException.class); assertThat(thrown.getMessage()).contains("closed"); diff --git a/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java b/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java index 5f13cf040..fa80f1364 100644 --- a/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java +++ b/resilience-tests/src/test/java/resilience/timeout/TimeoutClusterTest.java @@ -30,7 +30,7 @@ class TimeoutClusterTest extends ClusterTest { @MethodSource("protocolProvider") void requestTimeout(Protocol protocol) throws InterruptedException { ArangoDB arangoDB = dbBuilder() - .timeout(1_000) + .timeout(500) .protocol(protocol) .build(); @@ -41,7 +41,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { col.truncate(); Throwable thrown = catchThrowable(() -> arangoDB.db() - .query("INSERT {value:sleep(2)} INTO @@col RETURN NEW", + .query("INSERT {value:sleep(1)} INTO @@col RETURN NEW", Map.class, Collections.singletonMap("@col", colName)) ); @@ -53,7 +53,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { arangoDB.getVersion(); - Thread.sleep(2_000); + Thread.sleep(1_000); assertThat(col.count().getCount()).isEqualTo(1); arangoDB.shutdown(); @@ -71,7 +71,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { @MethodSource("protocolProvider") void requestTimeoutAsync(Protocol protocol) throws InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() - .timeout(1_000) + .timeout(500) .protocol(protocol) .build() .async(); @@ -83,7 +83,7 @@ void requestTimeoutAsync(Protocol protocol) throws InterruptedException, Executi col.truncate().get(); Throwable thrown = catchThrowable(() -> arangoDB.db() - .query("INSERT {value:sleep(2)} INTO @@col RETURN NEW", + .query("INSERT {value:sleep(1)} INTO @@col RETURN NEW", Map.class, Collections.singletonMap("@col", colName)).get() ).getCause(); @@ -95,7 +95,7 @@ void requestTimeoutAsync(Protocol protocol) throws InterruptedException, Executi arangoDB.getVersion().get(); - Thread.sleep(2_000); + Thread.sleep(1_000); assertThat(col.count().get().getCount()).isEqualTo(1); arangoDB.shutdown(); diff --git a/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java b/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java index 24882f0bc..3f9481223 100644 --- a/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java +++ b/resilience-tests/src/test/java/resilience/timeout/TimeoutTest.java @@ -31,7 +31,7 @@ class TimeoutTest extends SingleServerTest { @MethodSource("protocolProvider") void requestTimeout(Protocol protocol) throws InterruptedException { ArangoDB arangoDB = dbBuilder() - .timeout(1_000) + .timeout(500) .protocol(protocol) .build(); @@ -42,7 +42,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { col.truncate(); Throwable thrown = catchThrowable(() -> arangoDB.db() - .query("INSERT {value:sleep(2)} INTO @@col RETURN NEW", + .query("INSERT {value:sleep(1)} INTO @@col RETURN NEW", Map.class, Collections.singletonMap("@col", colName)) ); @@ -54,7 +54,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { arangoDB.getVersion(); - Thread.sleep(2_000); + Thread.sleep(1_000); assertThat(col.count().getCount()).isEqualTo(1); arangoDB.shutdown(); @@ -72,7 +72,7 @@ void requestTimeout(Protocol protocol) throws InterruptedException { @MethodSource("protocolProvider") void requestTimeoutAsync(Protocol protocol) throws InterruptedException, ExecutionException { ArangoDBAsync arangoDB = dbBuilder() - .timeout(1_000) + .timeout(500) .protocol(protocol) .build() .async(); @@ -84,7 +84,7 @@ void requestTimeoutAsync(Protocol protocol) throws InterruptedException, Executi col.truncate().get(); Throwable thrown = catchThrowable(() -> arangoDB.db() - .query("INSERT {value:sleep(2)} INTO @@col RETURN NEW", + .query("INSERT {value:sleep(1)} INTO @@col RETURN NEW", Map.class, Collections.singletonMap("@col", colName)).get() ).getCause(); @@ -96,7 +96,7 @@ void requestTimeoutAsync(Protocol protocol) throws InterruptedException, Executi arangoDB.getVersion().get(); - Thread.sleep(2_000); + Thread.sleep(1_000); assertThat(col.count().get().getCount()).isEqualTo(1); arangoDB.shutdown(); From a4dd9d11cc1871742995e74d779951e9b07d1d90 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 27 Feb 2024 22:38:35 +0100 Subject: [PATCH 10/10] resilience tests: db version matrix --- .github/workflows/resilience.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/resilience.yml b/.github/workflows/resilience.yml index e190a6155..257786e35 100644 --- a/.github/workflows/resilience.yml +++ b/.github/workflows/resilience.yml @@ -23,6 +23,15 @@ jobs: timeout-minutes: 20 runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - docker-img: docker.io/arangodb/enterprise:3.11.7 + compression: false + - docker-img: docker.io/arangodb/arangodb-preview:devel-nightly + compression: true + env: TOXIPROXY_VERSION: v2.7.0 @@ -38,8 +47,8 @@ jobs: run: ./docker/start_db.sh env: STARTER_MODE: cluster - DOCKER_IMAGE: docker.io/arangodb/arangodb-preview:devel-nightly - COMPRESSION: true + DOCKER_IMAGE: ${{matrix.docker-img}} + COMPRESSION: ${{matrix.compression}} - name: Info run: mvn -version - name: Start Toxiproxy