diff --git a/java/DEVELOPER.md b/java/DEVELOPER.md index bd04f278af..68180e2938 100644 --- a/java/DEVELOPER.md +++ b/java/DEVELOPER.md @@ -232,6 +232,12 @@ To run end-to-end tests, use the following command: ./gradlew :integTest:test ``` +IT suite start the server for testing - standalone and cluster installation using `cluster_manager` script. +By default, it starts servers without TLS; to activate TLS add `-Dtls=true` to the command line: +```bash +./gradlew :integTest:test -Dtls=true +``` + To run a single test, use the following command: ```bash ./gradlew :integTest:test --tests '*.functionLoad_and_functionList' --rerun @@ -242,6 +248,21 @@ To run one class, use the following command: ./gradlew :client:test --tests 'TransactionTests' --rerun ``` +To run IT tests against an existing cluster and/or standalone endpoint, use: +```bash +./gradlew :integTest:test -Dcluster-endpoints=localhost:7000 -Dstandalone-endpoints=localhost:6379 +``` + +If those endpoints use TLS, add `-Dtls=true` (applied to both endpoints): +```bash +./gradlew :integTest:test -Dcluster-endpoints=localhost:7000 -Dstandalone-endpoints=localhost:6379 -Dtls=true +``` + +You can combine this with test filter as well: +```bash +./gradlew :integTest:test -Dcluster-endpoints=localhost:7000 -Dstandalone-endpoints=localhost:6379 --tests 'TransactionTests' -Dtls=true +``` + ### Generate files To (re)generate protobuf code, use the following command: diff --git a/java/integTest/build.gradle b/java/integTest/build.gradle index 2b56978a08..961860dc6c 100644 --- a/java/integTest/build.gradle +++ b/java/integTest/build.gradle @@ -30,21 +30,18 @@ dependencies { testAnnotationProcessor 'org.projectlombok:lombok:1.18.32' } -def standalonePorts = [] -def clusterPorts = [] +def standaloneHosts = '' +def clusterHosts = '' ext { - extractPortsFromClusterManagerOutput = { String output -> - var res = [] + extractAddressesFromClusterManagerOutput = { String output -> for (def line : output.split("\n")) { if (!line.startsWith("CLUSTER_NODES=")) continue - def addresses = line.split("=")[1].split(",") - for (def address : addresses) - res << address.split(":")[1] + return line.split("=")[1] } - return res + return '' } } @@ -69,26 +66,38 @@ tasks.register('clearDirs', Delete) { tasks.register('startCluster') { doLast { - new ByteArrayOutputStream().withStream { os -> - exec { - workingDir "${project.rootDir}/../utils" - commandLine 'python3', 'cluster_manager.py', 'start', '--cluster-mode' - standardOutput = os + if (System.getProperty("cluster-endpoints") == null) { + new ByteArrayOutputStream().withStream { os -> + exec { + workingDir "${project.rootDir}/../utils" + def args = ['python3', 'cluster_manager.py', 'start', '--cluster-mode'] + if (System.getProperty("tls") == 'true') args.add(2, '--tls') + commandLine args + standardOutput = os + } + clusterHosts = extractAddressesFromClusterManagerOutput(os.toString()) } - clusterPorts = extractPortsFromClusterManagerOutput(os.toString()) + } else { + clusterHosts = System.getProperty("cluster-endpoints") } } } tasks.register('startStandalone') { doLast { - new ByteArrayOutputStream().withStream { os -> - exec { - workingDir "${project.rootDir}/../utils" - commandLine 'python3', 'cluster_manager.py', 'start', '-r', '0' - standardOutput = os + if (System.getProperty("standalone-endpoints") == null) { + new ByteArrayOutputStream().withStream { os -> + exec { + workingDir "${project.rootDir}/../utils" + def args = ['python3', 'cluster_manager.py', 'start', '-r', '0'] + if (System.getProperty("tls") == 'true') args.add(2, '--tls') + commandLine args + standardOutput = os + } + standaloneHosts = extractAddressesFromClusterManagerOutput(os.toString()) } - standalonePorts = extractPortsFromClusterManagerOutput(os.toString()) + } else { + standaloneHosts = System.getProperty("standalone-endpoints") } } } @@ -103,10 +112,11 @@ test.dependsOn ':client:buildRustRelease' tasks.withType(Test) { doFirst { - println "Cluster ports = ${clusterPorts}" - println "Standalone ports = ${standalonePorts}" - systemProperty 'test.server.standalone.ports', standalonePorts.join(',') - systemProperty 'test.server.cluster.ports', clusterPorts.join(',') + println "Cluster hosts = ${clusterHosts}" + println "Standalone hosts = ${standaloneHosts}" + systemProperty 'test.server.standalone', standaloneHosts + systemProperty 'test.server.cluster', clusterHosts + systemProperty 'test.server.tls', System.getProperty("tls") } testLogging { diff --git a/java/integTest/src/test/java/glide/ConnectionTests.java b/java/integTest/src/test/java/glide/ConnectionTests.java index 9bca84c108..de17f54e1c 100644 --- a/java/integTest/src/test/java/glide/ConnectionTests.java +++ b/java/integTest/src/test/java/glide/ConnectionTests.java @@ -1,9 +1,11 @@ /** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */ package glide; +import static glide.TestUtilities.commonClientConfig; +import static glide.TestUtilities.commonClusterClientConfig; + import glide.api.GlideClient; -import glide.api.models.configuration.GlideClientConfiguration; -import glide.api.models.configuration.NodeAddress; +import glide.api.GlideClusterClient; import lombok.SneakyThrows; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; @@ -14,25 +16,14 @@ public class ConnectionTests { @Test @SneakyThrows public void basic_client() { - var regularClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address( - NodeAddress.builder().port(TestConfiguration.STANDALONE_PORTS[0]).build()) - .build()) - .get(); + var regularClient = GlideClient.createClient(commonClientConfig().build()).get(); regularClient.close(); } @Test @SneakyThrows public void cluster_client() { - var regularClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address(NodeAddress.builder().port(TestConfiguration.CLUSTER_PORTS[0]).build()) - .build()) - .get(); - regularClient.close(); + var clusterClient = GlideClusterClient.createClient(commonClusterClientConfig().build()).get(); + clusterClient.close(); } } diff --git a/java/integTest/src/test/java/glide/CustomThreadPoolResourceTest.java b/java/integTest/src/test/java/glide/CustomThreadPoolResourceTest.java index ce1817022a..fbf2faab66 100644 --- a/java/integTest/src/test/java/glide/CustomThreadPoolResourceTest.java +++ b/java/integTest/src/test/java/glide/CustomThreadPoolResourceTest.java @@ -1,11 +1,10 @@ /** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */ package glide; +import static glide.TestUtilities.commonClientConfig; import static org.junit.jupiter.api.Assertions.assertEquals; import glide.api.GlideClient; -import glide.api.models.configuration.GlideClientConfiguration; -import glide.api.models.configuration.NodeAddress; import glide.connectors.resources.EpollResource; import glide.connectors.resources.KQueuePoolResource; import glide.connectors.resources.Platform; @@ -33,11 +32,7 @@ public void standalone_client_with_custom_threadPoolResource() { var regularClient = GlideClient.createClient( - GlideClientConfiguration.builder() - .address( - NodeAddress.builder().port(TestConfiguration.STANDALONE_PORTS[0]).build()) - .threadPoolResource(customThreadPoolResource) - .build()) + commonClientConfig().threadPoolResource(customThreadPoolResource).build()) .get(10, TimeUnit.SECONDS); String payload = (String) regularClient.customCommand(new String[] {"PING"}).get(); diff --git a/java/integTest/src/test/java/glide/ErrorHandlingTests.java b/java/integTest/src/test/java/glide/ErrorHandlingTests.java index a3a56a16ac..5b64e37d50 100644 --- a/java/integTest/src/test/java/glide/ErrorHandlingTests.java +++ b/java/integTest/src/test/java/glide/ErrorHandlingTests.java @@ -1,6 +1,7 @@ /** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */ package glide; +import static glide.TestUtilities.commonClientConfig; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -39,13 +40,7 @@ public void basic_client_tries_to_connect_to_wrong_address() { @Test @SneakyThrows public void basic_client_tries_wrong_command() { - try (var regularClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address( - NodeAddress.builder().port(TestConfiguration.STANDALONE_PORTS[0]).build()) - .build()) - .get()) { + try (var regularClient = GlideClient.createClient(commonClientConfig().build()).get()) { var exception = assertThrows( ExecutionException.class, @@ -59,13 +54,7 @@ public void basic_client_tries_wrong_command() { @Test @SneakyThrows public void basic_client_tries_wrong_command_arguments() { - try (var regularClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address( - NodeAddress.builder().port(TestConfiguration.STANDALONE_PORTS[0]).build()) - .build()) - .get()) { + try (var regularClient = GlideClient.createClient(commonClientConfig().build()).get()) { var exception = assertThrows( ExecutionException.class, diff --git a/java/integTest/src/test/java/glide/SharedCommandTests.java b/java/integTest/src/test/java/glide/SharedCommandTests.java index 3224f45c5c..88e0256a69 100644 --- a/java/integTest/src/test/java/glide/SharedCommandTests.java +++ b/java/integTest/src/test/java/glide/SharedCommandTests.java @@ -1,9 +1,7 @@ /** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */ package glide; -import static glide.TestConfiguration.CLUSTER_PORTS; import static glide.TestConfiguration.SERVER_VERSION; -import static glide.TestConfiguration.STANDALONE_PORTS; import static glide.TestUtilities.assertDeepEquals; import static glide.TestUtilities.commonClientConfig; import static glide.TestUtilities.commonClusterClientConfig; @@ -103,9 +101,6 @@ import glide.api.models.commands.stream.StreamReadOptions; import glide.api.models.commands.stream.StreamTrimOptions.MaxLen; import glide.api.models.commands.stream.StreamTrimOptions.MinId; -import glide.api.models.configuration.GlideClientConfiguration; -import glide.api.models.configuration.GlideClusterClientConfiguration; -import glide.api.models.configuration.NodeAddress; import glide.api.models.exceptions.RequestException; import java.time.Instant; import java.util.Arrays; @@ -149,19 +144,10 @@ public class SharedCommandTests { @SneakyThrows public static void init() { standaloneClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address(NodeAddress.builder().port(STANDALONE_PORTS[0]).build()) - .requestTimeout(5000) - .build()) - .get(); + GlideClient.createClient(commonClientConfig().requestTimeout(5000).build()).get(); clusterClient = - GlideClusterClient.createClient( - GlideClusterClientConfiguration.builder() - .address(NodeAddress.builder().port(CLUSTER_PORTS[0]).build()) - .requestTimeout(5000) - .build()) + GlideClusterClient.createClient(commonClusterClientConfig().requestTimeout(5000).build()) .get(); clients = List.of(Arguments.of(standaloneClient), Arguments.of(clusterClient)); diff --git a/java/integTest/src/test/java/glide/TestConfiguration.java b/java/integTest/src/test/java/glide/TestConfiguration.java index a57c1928b7..e2f77e6547 100644 --- a/java/integTest/src/test/java/glide/TestConfiguration.java +++ b/java/integTest/src/test/java/glide/TestConfiguration.java @@ -2,22 +2,30 @@ package glide; import static glide.TestUtilities.commonClientConfig; +import static glide.TestUtilities.commonClusterClientConfig; import com.vdurmont.semver4j.Semver; +import glide.api.BaseClient; import glide.api.GlideClient; -import java.util.Arrays; +import glide.api.GlideClusterClient; public final class TestConfiguration { // All servers are hosted on localhost - public static final int[] STANDALONE_PORTS = getPortsFromProperty("test.server.standalone.ports"); - public static final int[] CLUSTER_PORTS = getPortsFromProperty("test.server.cluster.ports"); + public static final String[] STANDALONE_HOSTS = + System.getProperty("test.server.standalone", "").split(","); + public static final String[] CLUSTER_HOSTS = + System.getProperty("test.server.cluster", "").split(","); public static final Semver SERVER_VERSION; + public static final boolean TLS = Boolean.parseBoolean(System.getProperty("test.server.tls", "")); static { try { - String serverVersion = - TestUtilities.getServerVersion( - GlideClient.createClient(commonClientConfig().build()).get()); + BaseClient client = + !STANDALONE_HOSTS[0].isEmpty() + ? GlideClient.createClient(commonClientConfig().build()).get() + : GlideClusterClient.createClient(commonClusterClientConfig().build()).get(); + + String serverVersion = TestUtilities.getServerVersion(client); if (serverVersion != null) { SERVER_VERSION = new Semver(serverVersion); } else { @@ -28,10 +36,4 @@ public final class TestConfiguration { throw new RuntimeException("Failed to get server version", e); } } - - private static int[] getPortsFromProperty(String propName) { - return Arrays.stream(System.getProperty(propName).split(",")) - .mapToInt(Integer::parseInt) - .toArray(); - } } diff --git a/java/integTest/src/test/java/glide/TestUtilities.java b/java/integTest/src/test/java/glide/TestUtilities.java index e7fc3c02cf..1429f62c97 100644 --- a/java/integTest/src/test/java/glide/TestUtilities.java +++ b/java/integTest/src/test/java/glide/TestUtilities.java @@ -1,9 +1,11 @@ /** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */ package glide; -import static glide.TestConfiguration.CLUSTER_PORTS; -import static glide.TestConfiguration.STANDALONE_PORTS; +import static glide.TestConfiguration.CLUSTER_HOSTS; +import static glide.TestConfiguration.STANDALONE_HOSTS; +import static glide.TestConfiguration.TLS; import static glide.api.models.GlideString.gs; +import static glide.api.models.configuration.RequestRoutingConfiguration.SimpleSingleNodeRoute.RANDOM; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -87,14 +89,24 @@ public static Map parseInfoResponseToMap(String serverInfo) { public static GlideClientConfiguration.GlideClientConfigurationBuilder commonClientConfig() { - return GlideClientConfiguration.builder() - .address(NodeAddress.builder().port(STANDALONE_PORTS[0]).build()); + var builder = GlideClientConfiguration.builder(); + for (var host : STANDALONE_HOSTS) { + var parts = host.split(":"); + builder.address( + NodeAddress.builder().host(parts[0]).port(Integer.parseInt(parts[1])).build()); + } + return builder.useTLS(TLS); } public static GlideClusterClientConfiguration.GlideClusterClientConfigurationBuilder commonClusterClientConfig() { - return GlideClusterClientConfiguration.builder() - .address(NodeAddress.builder().port(CLUSTER_PORTS[0]).build()); + var builder = GlideClusterClientConfiguration.builder(); + for (var host : CLUSTER_HOSTS) { + var parts = host.split(":"); + builder.address( + NodeAddress.builder().host(parts[0]).port(Integer.parseInt(parts[1])).build()); + } + return builder.useTLS(TLS); } /** @@ -405,12 +417,18 @@ public static void waitForNotBusy(BaseClient client) { /** * This method returns the server version using a glide client. * - * @param glideClient Glide client to be used for running the info command. + * @param client Glide client to be used for running the info command. * @return String The server version number. */ @SneakyThrows - public static String getServerVersion(@NonNull final GlideClient glideClient) { - String infoResponse = glideClient.info(new Section[] {Section.SERVER}).get(); + public static String getServerVersion(@NonNull final BaseClient client) { + String infoResponse = + client instanceof GlideClient + ? ((GlideClient) client).info(new Section[] {Section.SERVER}).get() + : ((GlideClusterClient) client) + .info(new Section[] {Section.SERVER}, RANDOM) + .get() + .getSingleValue(); Map infoResponseMap = parseInfoResponseToMap(infoResponse); if (infoResponseMap.containsKey(VALKEY_VERSION_KEY)) { return infoResponseMap.get(VALKEY_VERSION_KEY); diff --git a/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java b/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java index 4f5c2a7918..ef07e85267 100644 --- a/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java +++ b/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java @@ -3,6 +3,7 @@ import static glide.TestConfiguration.SERVER_VERSION; import static glide.TestUtilities.assertDeepEquals; +import static glide.TestUtilities.commonClusterClientConfig; import static glide.TestUtilities.generateLuaLibCode; import static glide.api.BaseClient.OK; import static glide.api.models.GlideString.gs; @@ -16,7 +17,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; -import glide.TestConfiguration; import glide.TransactionTestUtilities.TransactionBuilder; import glide.api.GlideClusterClient; import glide.api.models.ClusterTransaction; @@ -24,8 +24,6 @@ import glide.api.models.commands.SortOptions; import glide.api.models.commands.function.FunctionRestorePolicy; import glide.api.models.commands.stream.StreamAddOptions; -import glide.api.models.configuration.GlideClusterClientConfiguration; -import glide.api.models.configuration.NodeAddress; import glide.api.models.configuration.RequestRoutingConfiguration.SingleNodeRoute; import glide.api.models.configuration.RequestRoutingConfiguration.SlotIdRoute; import glide.api.models.configuration.RequestRoutingConfiguration.SlotType; @@ -51,11 +49,7 @@ public class ClusterTransactionTests { @SneakyThrows public static void init() { clusterClient = - GlideClusterClient.createClient( - GlideClusterClientConfiguration.builder() - .address(NodeAddress.builder().port(TestConfiguration.CLUSTER_PORTS[0]).build()) - .requestTimeout(5000) - .build()) + GlideClusterClient.createClient(commonClusterClientConfig().requestTimeout(5000).build()) .get(); }