diff --git a/java/client/src/main/java/glide/api/models/configuration/BaseClientConfiguration.java b/java/client/src/main/java/glide/api/models/configuration/BaseClientConfiguration.java index b6cc4e26ff..8a39557ae0 100644 --- a/java/client/src/main/java/glide/api/models/configuration/BaseClientConfiguration.java +++ b/java/client/src/main/java/glide/api/models/configuration/BaseClientConfiguration.java @@ -65,5 +65,11 @@ public abstract class BaseClientConfiguration { */ private final ThreadPoolResource threadPoolResource; + /** + * Serialization protocol to be used with the server. If not set, {@link ProtocolVersion#RESP3} + * will be used. + */ + private final ProtocolVersion protocol; + public abstract BaseSubscriptionConfiguration getSubscriptionConfiguration(); } diff --git a/java/client/src/main/java/glide/api/models/configuration/ProtocolVersion.java b/java/client/src/main/java/glide/api/models/configuration/ProtocolVersion.java new file mode 100644 index 0000000000..38fd6c2a1a --- /dev/null +++ b/java/client/src/main/java/glide/api/models/configuration/ProtocolVersion.java @@ -0,0 +1,10 @@ +/** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */ +package glide.api.models.configuration; + +/** Represents the communication protocol with the server. */ +public enum ProtocolVersion { + /** Use RESP2 to communicate with the server nodes. */ + RESP3, + /** Use RESP3 to communicate with the server nodes. */ + RESP2 +} diff --git a/java/client/src/main/java/glide/managers/ConnectionManager.java b/java/client/src/main/java/glide/managers/ConnectionManager.java index 58328d375c..893935361c 100644 --- a/java/client/src/main/java/glide/managers/ConnectionManager.java +++ b/java/client/src/main/java/glide/managers/ConnectionManager.java @@ -12,8 +12,10 @@ import glide.api.models.configuration.GlideClientConfiguration; import glide.api.models.configuration.GlideClusterClientConfiguration; import glide.api.models.configuration.NodeAddress; +import glide.api.models.configuration.ProtocolVersion; import glide.api.models.configuration.ReadFrom; import glide.api.models.exceptions.ClosingException; +import glide.api.models.exceptions.ConfigurationError; import glide.connectors.handlers.ChannelHandler; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @@ -118,6 +120,10 @@ private ConnectionRequest.Builder setupConnectionRequestBuilderBaseConfiguration connectionRequestBuilder.setClientName(configuration.getClientName()); } + if (configuration.getProtocol() != null) { + connectionRequestBuilder.setProtocolValue(configuration.getProtocol().ordinal()); + } + return connectionRequestBuilder; } @@ -145,7 +151,10 @@ private ConnectionRequest.Builder setupConnectionRequestBuilderGlideClient( } if (configuration.getSubscriptionConfiguration() != null) { - // TODO throw ConfigurationError if RESP2 + if (configuration.getProtocol() == ProtocolVersion.RESP2) { + throw new ConfigurationError( + "PubSub subscriptions require RESP3 protocol, but RESP2 was configured."); + } var subscriptionsBuilder = PubSubSubscriptions.newBuilder(); for (var entry : configuration.getSubscriptionConfiguration().getSubscriptions().entrySet()) { var channelsBuilder = PubSubChannelsOrPatterns.newBuilder(); diff --git a/java/client/src/test/java/glide/managers/ConnectionManagerTest.java b/java/client/src/test/java/glide/managers/ConnectionManagerTest.java index 9a3ebe6e19..5920ff0fde 100644 --- a/java/client/src/test/java/glide/managers/ConnectionManagerTest.java +++ b/java/client/src/test/java/glide/managers/ConnectionManagerTest.java @@ -28,6 +28,7 @@ import glide.api.models.configuration.GlideClientConfiguration; import glide.api.models.configuration.GlideClusterClientConfiguration; import glide.api.models.configuration.NodeAddress; +import glide.api.models.configuration.ProtocolVersion; import glide.api.models.configuration.ReadFrom; import glide.api.models.configuration.ServerCredentials; import glide.api.models.configuration.StandaloneSubscriptionConfiguration; @@ -143,6 +144,7 @@ public void connection_request_protobuf_generation_with_all_fields_set() { .build()) .databaseId(DATABASE_ID) .clientName(CLIENT_NAME) + .protocol(ProtocolVersion.RESP2) .subscriptionConfiguration( StandaloneSubscriptionConfiguration.builder() .subscription(EXACT, gs("channel_1")) @@ -176,6 +178,7 @@ public void connection_request_protobuf_generation_with_all_fields_set() { .build()) .setDatabaseId(DATABASE_ID) .setClientName(CLIENT_NAME) + .setProtocol(ConnectionRequestOuterClass.ProtocolVersion.RESP2) .setPubsubSubscriptions( PubSubSubscriptions.newBuilder() .putAllChannelsOrPatternsByType( diff --git a/java/integTest/src/test/java/glide/ConnectionTests.java b/java/integTest/src/test/java/glide/ConnectionTests.java index 9bca84c108..696d4f0a11 100644 --- a/java/integTest/src/test/java/glide/ConnectionTests.java +++ b/java/integTest/src/test/java/glide/ConnectionTests.java @@ -1,38 +1,36 @@ /** 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 glide.api.models.configuration.ProtocolVersion; import lombok.SneakyThrows; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; @Timeout(10) // seconds public class ConnectionTests { - @Test + @ParameterizedTest + @EnumSource(ProtocolVersion.class) @SneakyThrows - public void basic_client() { + public void basic_client(ProtocolVersion protocol) { var regularClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address( - NodeAddress.builder().port(TestConfiguration.STANDALONE_PORTS[0]).build()) - .build()) - .get(); + GlideClient.createClient(commonClientConfig().protocol(protocol).build()).get(); regularClient.close(); } - @Test + @ParameterizedTest + @EnumSource(ProtocolVersion.class) @SneakyThrows - public void cluster_client() { - var regularClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address(NodeAddress.builder().port(TestConfiguration.CLUSTER_PORTS[0]).build()) - .build()) + public void cluster_client(ProtocolVersion protocol) { + var clusterClient = + GlideClusterClient.createClient(commonClusterClientConfig().protocol(protocol).build()) .get(); - regularClient.close(); + clusterClient.close(); } } diff --git a/java/integTest/src/test/java/glide/PubSubTests.java b/java/integTest/src/test/java/glide/PubSubTests.java index e4eeab6cad..62277691c0 100644 --- a/java/integTest/src/test/java/glide/PubSubTests.java +++ b/java/integTest/src/test/java/glide/PubSubTests.java @@ -27,6 +27,7 @@ import glide.api.models.configuration.BaseSubscriptionConfiguration.MessageCallback; import glide.api.models.configuration.ClusterSubscriptionConfiguration; import glide.api.models.configuration.ClusterSubscriptionConfiguration.PubSubClusterChannelMode; +import glide.api.models.configuration.ProtocolVersion; import glide.api.models.configuration.RequestRoutingConfiguration.SlotKeyRoute; import glide.api.models.configuration.RequestRoutingConfiguration.SlotType; import glide.api.models.configuration.StandaloneSubscriptionConfiguration; @@ -280,6 +281,32 @@ private void skipTestsOnMac() { "PubSub doesn't work on mac OS"); } + @SneakyThrows + @ParameterizedTest(name = "standalone = {0}") + @ValueSource(booleans = {true, false}) + public void config_error_on_resp2(boolean standalone) { + final GlideString channel = gs(UUID.randomUUID().toString()); + + Map> subscriptions = + standalone + ? Map.of(PubSubChannelMode.EXACT, Set.of(channel)) + : Map.of(PubSubClusterChannelMode.EXACT, Set.of(channel)); + + var exception = + assertThrows( + ConfigurationError.class, + () -> + GlideClient.createClient( + commonClientConfig() + .subscriptionConfiguration( + StandaloneSubscriptionConfiguration + .builder() /*.subscriptions(subscriptions)*/ + .build()) + .protocol(ProtocolVersion.RESP2) + .build())); + assertTrue(exception.getMessage().contains("PubSub subscriptions require RESP3 protocol")); + } + /** Similar to `test_pubsub_exact_happy_path` in python client tests. */ @SneakyThrows @ParameterizedTest(name = "standalone = {0}, read messages via {1}") diff --git a/java/integTest/src/test/java/glide/SharedCommandTests.java b/java/integTest/src/test/java/glide/SharedCommandTests.java index 3224f45c5c..b04506a7fc 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; @@ -30,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Named.named; import glide.api.BaseClient; import glide.api.GlideClient; @@ -103,11 +102,10 @@ 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.configuration.ProtocolVersion; import glide.api.models.exceptions.RequestException; import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -127,6 +125,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Named; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; @@ -136,10 +135,7 @@ @Timeout(10) // seconds public class SharedCommandTests { - private static GlideClient standaloneClient = null; - private static GlideClusterClient clusterClient = null; - - @Getter private static List clients; + @Getter private static final List clients = new ArrayList<>(); private static final String KEY_NAME = "key"; private static final String INITIAL_VALUE = "VALUE"; @@ -148,30 +144,31 @@ public class SharedCommandTests { @BeforeAll @SneakyThrows public static void init() { - standaloneClient = - GlideClient.createClient( - GlideClientConfiguration.builder() - .address(NodeAddress.builder().port(STANDALONE_PORTS[0]).build()) - .requestTimeout(5000) - .build()) - .get(); + for (var protocol : ProtocolVersion.values()) { + var standaloneClient = + GlideClient.createClient( + commonClientConfig().requestTimeout(5000).protocol(protocol).build()) + .get(); - clusterClient = - GlideClusterClient.createClient( - GlideClusterClientConfiguration.builder() - .address(NodeAddress.builder().port(CLUSTER_PORTS[0]).build()) - .requestTimeout(5000) - .build()) - .get(); + var clusterClient = + GlideClusterClient.createClient( + commonClusterClientConfig().requestTimeout(5000).protocol(protocol).build()) + .get(); - clients = List.of(Arguments.of(standaloneClient), Arguments.of(clusterClient)); + clients.addAll( + List.of( + Arguments.of(named("standalone " + protocol, standaloneClient)), + Arguments.of(named("cluster " + protocol, clusterClient)))); + } } @AfterAll @SneakyThrows + @SuppressWarnings("unchecked") public static void teardown() { - standaloneClient.close(); - clusterClient.close(); + for (var client : clients) { + ((Named) client.get()[0]).getPayload().close(); + } } @SneakyThrows @@ -380,7 +377,6 @@ public void getdel(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void getex(BaseClient client) { - assumeTrue( SERVER_VERSION.isGreaterThanOrEqualTo("6.2.0"), "This feature added in version 6.2.0"); @@ -427,7 +423,6 @@ public void getex(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void getex_binary(BaseClient client) { - assumeTrue( SERVER_VERSION.isGreaterThanOrEqualTo("6.2.0"), "This feature added in version 6.2.0"); @@ -474,7 +469,7 @@ public void getex_binary(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_only_if_exists_overwrite(BaseClient client) { - String key = "set_only_if_exists_overwrite"; + String key = UUID.randomUUID().toString(); SetOptions options = SetOptions.builder().conditionalSet(ONLY_IF_EXISTS).build(); client.set(key, INITIAL_VALUE).get(); client.set(key, ANOTHER_VALUE, options).get(); @@ -486,7 +481,7 @@ public void set_only_if_exists_overwrite(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_only_if_exists_missing_key(BaseClient client) { - String key = "set_only_if_exists_missing_key"; + String key = UUID.randomUUID().toString(); SetOptions options = SetOptions.builder().conditionalSet(ONLY_IF_EXISTS).build(); client.set(key, ANOTHER_VALUE, options).get(); String data = client.get(key).get(); @@ -497,7 +492,7 @@ public void set_only_if_exists_missing_key(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_only_if_does_not_exists_missing_key(BaseClient client) { - String key = "set_only_if_does_not_exists_missing_key"; + String key = UUID.randomUUID().toString(); SetOptions options = SetOptions.builder().conditionalSet(ONLY_IF_DOES_NOT_EXIST).build(); client.set(key, ANOTHER_VALUE, options).get(); String data = client.get(key).get(); @@ -508,7 +503,7 @@ public void set_only_if_does_not_exists_missing_key(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_get_binary_data(BaseClient client) { - GlideString key = gs("set_get_binary_data_key"); + GlideString key = gs(UUID.randomUUID().toString()); byte[] binvalue = {(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02}; assertEquals(client.set(key, gs(binvalue)).get(), "OK"); GlideString data = client.get(key).get(); @@ -520,7 +515,7 @@ public void set_get_binary_data(BaseClient client) { @MethodSource("getClients") public void set_get_binary_data_with_options(BaseClient client) { SetOptions options = SetOptions.builder().conditionalSet(ONLY_IF_DOES_NOT_EXIST).build(); - GlideString key = gs("set_get_binary_data_with_options"); + GlideString key = gs(UUID.randomUUID().toString()); byte[] binvalue = {(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02}; assertEquals(client.set(key, gs(binvalue), options).get(), "OK"); GlideString data = client.get(key).get(); @@ -531,7 +526,7 @@ public void set_get_binary_data_with_options(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_only_if_does_not_exists_existing_key(BaseClient client) { - String key = "set_only_if_does_not_exists_existing_key"; + String key = UUID.randomUUID().toString(); SetOptions options = SetOptions.builder().conditionalSet(ONLY_IF_DOES_NOT_EXIST).build(); client.set(key, INITIAL_VALUE).get(); client.set(key, ANOTHER_VALUE, options).get(); @@ -543,7 +538,7 @@ public void set_only_if_does_not_exists_existing_key(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_value_with_ttl_and_update_value_with_keeping_ttl(BaseClient client) { - String key = "set_value_with_ttl_and_update_value_with_keeping_ttl"; + String key = UUID.randomUUID().toString(); SetOptions options = SetOptions.builder().expiry(Milliseconds(2000L)).build(); client.set(key, INITIAL_VALUE, options).get(); String data = client.get(key).get(); @@ -564,7 +559,7 @@ public void set_value_with_ttl_and_update_value_with_keeping_ttl(BaseClient clie @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_value_with_ttl_and_update_value_with_new_ttl(BaseClient client) { - String key = "set_value_with_ttl_and_update_value_with_new_ttl"; + String key = UUID.randomUUID().toString(); SetOptions options = SetOptions.builder().expiry(Milliseconds(100500L)).build(); client.set(key, INITIAL_VALUE, options).get(); String data = client.get(key).get(); @@ -585,7 +580,7 @@ public void set_value_with_ttl_and_update_value_with_new_ttl(BaseClient client) @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void set_expired_value(BaseClient client) { - String key = "set_expired_value"; + String key = UUID.randomUUID().toString(); SetOptions options = SetOptions.builder() // expiration is in the past @@ -986,7 +981,8 @@ public void non_UTF8_GlideString_map(BaseClient client) { byte[] nonUTF8Bytes = new byte[] {(byte) 0xEE}; GlideString key = gs(nonUTF8Bytes); GlideString hashKey = gs(UUID.randomUUID().toString()); - GlideString hashNonUTF8Key = gs(new byte[] {(byte) 0xDD}); + GlideString hashNonUTF8Key = + gs(new byte[] {(byte) 0xDD}).concat(gs(UUID.randomUUID().toString())); GlideString value = gs(nonUTF8Bytes); String stringField = "field"; Map fieldValueMap = Map.of(gs(stringField), value); @@ -1019,7 +1015,7 @@ public void non_UTF8_GlideString_map(BaseClient client) { public void non_UTF8_GlideString_map_with_double(BaseClient client) { byte[] nonUTF8Bytes = new byte[] {(byte) 0xEE}; GlideString key = gs(UUID.randomUUID().toString()); - GlideString nonUTF8Key = gs(new byte[] {(byte) 0xEF}); + GlideString nonUTF8Key = gs(new byte[] {(byte) 0xEF}).concat(gs(UUID.randomUUID().toString())); Map membersScores = Map.of(gs(nonUTF8Bytes), 1.0, gs("two"), 2.0, gs("three"), 3.0); @@ -1048,7 +1044,7 @@ public void non_UTF8_GlideString_map_with_double(BaseClient client) { public void non_UTF8_GlideString_nested_array(BaseClient client) { byte[] nonUTF8Bytes = new byte[] {(byte) 0xEE}; GlideString key = gs(UUID.randomUUID().toString()); - GlideString nonUTF8Key = gs(new byte[] {(byte) 0xFF}); + GlideString nonUTF8Key = gs(new byte[] {(byte) 0xFF}).concat(gs(UUID.randomUUID().toString())); GlideString field = gs(nonUTF8Bytes); GlideString value1 = gs(nonUTF8Bytes); GlideString value2 = gs("foobar"); @@ -1085,7 +1081,7 @@ public void non_UTF8_GlideString_nested_array(BaseClient client) { public void non_UTF8_GlideString_map_with_geospatial(BaseClient client) { byte[] nonUTF8Bytes = new byte[] {(byte) 0xEE}; GlideString key = gs(UUID.randomUUID().toString()); - GlideString nonUTF8Key = gs(new byte[] {(byte) 0xDF}); + GlideString nonUTF8Key = gs(new byte[] {(byte) 0xDF}).concat(gs(UUID.randomUUID().toString())); Map membersToCoordinates = new HashMap<>(); membersToCoordinates.put(gs(nonUTF8Bytes), new GeospatialData(13.361389, 38.115556)); membersToCoordinates.put(gs("Catania"), new GeospatialData(15.087269, 37.502669)); @@ -1135,7 +1131,7 @@ public void non_UTF8_GlideString_map_with_geospatial(BaseClient client) { public void non_UTF8_GlideString_map_of_arrays(BaseClient client) { byte[] nonUTF8Bytes = new byte[] {(byte) 0xEE}; GlideString key = gs(UUID.randomUUID().toString()); - GlideString nonUTF8Key = gs(new byte[] {(byte) 0xFE}); + GlideString nonUTF8Key = gs(new byte[] {(byte) 0xFE}).concat(gs(UUID.randomUUID().toString())); GlideString[] lpushArgs = {gs(nonUTF8Bytes), gs("two")}; // Testing map of arrays using byte[] that cannot be converted to UTF-8 Strings. @@ -1633,8 +1629,8 @@ public void hrandfieldBinary(BaseClient client) { byte[] binvalue1 = {(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02}; byte[] binvalue2 = {(byte) 0xFF, (byte) 0x66, (byte) 0xFF, (byte) 0xAF, (byte) 0x22}; - GlideString key1 = gs(binvalue1); - GlideString key2 = gs(binvalue2); + GlideString key1 = gs(binvalue1).concat(gs(UUID.randomUUID().toString())); + GlideString key2 = gs(binvalue2).concat(gs(UUID.randomUUID().toString())); // key does not exist assertNull(client.hrandfield(key1).get()); @@ -8082,11 +8078,6 @@ public void xpending_xclaim_binary(BaseClient client) { Object[][] pending_results_extended = client.xpending(key, groupName, InfRangeBound.MIN, InfRangeBound.MAX, 10L).get(); - System.out.println("xpending result:"); - for (int i = 0; i < pending_results_extended.length; i++) { - System.out.println((GlideString) pending_results_extended[i][0]); - } - // because of idle time return, we have to remove it from the expected results // and check it separately assertArrayEquals( @@ -8121,9 +8112,6 @@ public void xpending_xclaim_binary(BaseClient client) { .get(); assertNotNull(claimResults); assertEquals(claimResults.size(), 2); - for (var e : claimResults.entrySet()) { - System.out.println("Key: " + e.getKey().getString()); - } assertNotNull(claimResults.get(streamid_5)); assertNotNull(claimResults.get(streamid_3)); @@ -12551,27 +12539,22 @@ public void sort_with_pattern(BaseClient client) { if (client instanceof GlideClusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), "This feature added in version 8"); } - String setKey1 = "{setKey}1"; - String setKey2 = "{setKey}2"; - String setKey3 = "{setKey}3"; - String setKey4 = "{setKey}4"; - String setKey5 = "{setKey}5"; - String[] setKeys = new String[] {setKey1, setKey2, setKey3, setKey4, setKey5}; - String listKey = "{setKey}listKey"; - String storeKey = "{setKey}storeKey"; + String prefix = "{setKey}-" + UUID.randomUUID(); + String listKey = prefix + "listKey"; + String storeKey = prefix + "storeKey"; String nameField = "name"; String ageField = "age"; String[] names = new String[] {"Alice", "Bob", "Charlie", "Dave", "Eve"}; String[] namesSortedByAge = new String[] {"Dave", "Bob", "Alice", "Charlie", "Eve"}; String[] ages = new String[] {"30", "25", "35", "20", "40"}; String[] userIDs = new String[] {"3", "1", "5", "4", "2"}; - String namePattern = "{setKey}*->name"; - String agePattern = "{setKey}*->age"; + String namePattern = prefix + "*->name"; + String agePattern = prefix + "*->age"; String missingListKey = "100000"; - for (int i = 0; i < setKeys.length; i++) { + for (int i = 0; i < names.length; i++) { assertEquals( - 2, client.hset(setKeys[i], Map.of(nameField, names[i], ageField, ages[i])).get()); + 2, client.hset(prefix + (i + 1), Map.of(nameField, names[i], ageField, ages[i])).get()); } assertEquals(5, client.rpush(listKey, userIDs).get()); @@ -12734,14 +12717,9 @@ public void sort_with_pattern_binary(BaseClient client) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), "This feature added in version 8"); } - GlideString setKey1 = gs("{setKeyGs}1"); - GlideString setKey2 = gs("{setKeyGs}2"); - GlideString setKey3 = gs("{setKeyGs}3"); - GlideString setKey4 = gs("{setKeyGs}4"); - GlideString setKey5 = gs("{setKeyGs}5"); - GlideString[] setKeys = new GlideString[] {setKey1, setKey2, setKey3, setKey4, setKey5}; - GlideString listKey = gs("{setKeyGs}listKey"); - GlideString storeKey = gs("{setKeyGs}storeKey"); + String prefix = "{setKey}-" + UUID.randomUUID(); + GlideString listKey = gs(prefix + "listKey"); + GlideString storeKey = gs(prefix + "storeKey"); GlideString nameField = gs("name"); GlideString ageField = gs("age"); GlideString[] names = @@ -12751,22 +12729,14 @@ public void sort_with_pattern_binary(BaseClient client) { new GlideString[] {gs("Dave"), gs("Bob"), gs("Alice"), gs("Charlie"), gs("Eve")}; GlideString[] ages = new GlideString[] {gs("30"), gs("25"), gs("35"), gs("20"), gs("40")}; GlideString[] userIDs = new GlideString[] {gs("3"), gs("1"), gs("5"), gs("4"), gs("2")}; - GlideString namePattern = gs("{setKeyGs}*->name"); - GlideString agePattern = gs("{setKeyGs}*->age"); + GlideString namePattern = gs(prefix + "*->name"); + GlideString agePattern = gs(prefix + "*->age"); GlideString missingListKey = gs("100000"); - for (int i = 0; i < setKeys.length; i++) { + for (int i = 0; i < names.length; i++) { assertEquals( 2, - client - .hset( - setKeys[i].toString(), - Map.of( - nameField.toString(), - names[i].toString(), - ageField.toString(), - ages[i].toString())) - .get()); + client.hset(gs(prefix + (i + 1)), Map.of(nameField, names[i], ageField, ages[i])).get()); } assertEquals(5, client.rpush(listKey, userIDs).get()); diff --git a/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java b/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java index 4f5c2a7918..62f65dcfe6 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; @@ -15,8 +16,8 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Named.named; -import glide.TestConfiguration; import glide.TransactionTestUtilities.TransactionBuilder; import glide.api.GlideClusterClient; import glide.api.models.ClusterTransaction; @@ -24,8 +25,7 @@ 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.ProtocolVersion; import glide.api.models.configuration.RequestRoutingConfiguration.SingleNodeRoute; import glide.api.models.configuration.RequestRoutingConfiguration.SlotIdRoute; import glide.api.models.configuration.RequestRoutingConfiguration.SlotType; @@ -34,48 +34,52 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; +import java.util.stream.Stream; import lombok.SneakyThrows; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @Timeout(10) // seconds public class ClusterTransactionTests { - private static GlideClusterClient clusterClient = null; - - @BeforeAll - @SneakyThrows - public static void init() { - clusterClient = - GlideClusterClient.createClient( - GlideClusterClientConfiguration.builder() - .address(NodeAddress.builder().port(TestConfiguration.CLUSTER_PORTS[0]).build()) - .requestTimeout(5000) - .build()) - .get(); - } - - @AfterAll @SneakyThrows - public static void teardown() { - clusterClient.close(); + public static Stream getClients() { + return Stream.of( + Arguments.of( + named( + "RESP2", + GlideClusterClient.createClient( + commonClusterClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP2) + .build()) + .get())), + Arguments.of( + named( + "RESP3", + GlideClusterClient.createClient( + commonClusterClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP3) + .build()) + .get()))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_info() { + public void custom_command_info(GlideClusterClient clusterClient) { ClusterTransaction transaction = new ClusterTransaction().customCommand(new String[] {"info"}); Object[] result = clusterClient.exec(transaction).get(); assertTrue(((String) result[0]).contains("# Stats")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_simple_route_test() { + public void info_simple_route_test(GlideClusterClient clusterClient) { ClusterTransaction transaction = new ClusterTransaction().info().info(); Object[] result = clusterClient.exec(transaction, RANDOM).get(); @@ -83,10 +87,19 @@ public void info_simple_route_test() { assertTrue(((String) result[1]).contains("# Stats")); } + public static Stream getCommonTransactionBuilders() { + return glide.TransactionTestUtilities.getCommonTransactionBuilders() + .flatMap( + test -> + getClients() + .map(client -> Arguments.of(test.get()[0], test.get()[1], client.get()[0]))); + } + @SneakyThrows @ParameterizedTest(name = "{0}") - @MethodSource("glide.TransactionTestUtilities#getCommonTransactionBuilders") - public void transactions_with_group_of_commands(String testName, TransactionBuilder builder) { + @MethodSource("getCommonTransactionBuilders") + public void transactions_with_group_of_commands( + String testName, TransactionBuilder builder, GlideClusterClient clusterClient) { ClusterTransaction transaction = new ClusterTransaction(); Object[] expectedResult = builder.apply(transaction); @@ -94,11 +107,19 @@ public void transactions_with_group_of_commands(String testName, TransactionBuil assertDeepEquals(expectedResult, results); } + public static Stream getPrimaryNodeTransactionBuilders() { + return glide.TransactionTestUtilities.getPrimaryNodeTransactionBuilders() + .flatMap( + test -> + getClients() + .map(client -> Arguments.of(test.get()[0], test.get()[1], client.get()[0]))); + } + @SneakyThrows @ParameterizedTest(name = "{0}") - @MethodSource("glide.TransactionTestUtilities#getPrimaryNodeTransactionBuilders") + @MethodSource("getPrimaryNodeTransactionBuilders") public void keyless_transactions_with_group_of_commands( - String testName, TransactionBuilder builder) { + String testName, TransactionBuilder builder, GlideClusterClient clusterClient) { ClusterTransaction transaction = new ClusterTransaction(); Object[] expectedResult = builder.apply(transaction); @@ -108,8 +129,9 @@ public void keyless_transactions_with_group_of_commands( } @SneakyThrows - @Test - public void test_transaction_large_values() { + @ParameterizedTest + @MethodSource("getClients") + public void test_transaction_large_values(GlideClusterClient clusterClient) { int length = 1 << 25; // 33mb String key = "0".repeat(length); String value = "0".repeat(length); @@ -128,17 +150,19 @@ public void test_transaction_large_values() { assertArrayEquals(expectedResult, result); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void lastsave() { + public void lastsave(GlideClusterClient clusterClient) { var yesterday = Instant.now().minus(1, ChronoUnit.DAYS); var response = clusterClient.exec(new ClusterTransaction().lastsave()).get(); assertTrue(Instant.ofEpochSecond((long) response[0]).isAfter(yesterday)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectFreq() { + public void objectFreq(GlideClusterClient clusterClient) { String objectFreqKey = "key"; String maxmemoryPolicy = "maxmemory-policy"; String oldPolicy = @@ -157,9 +181,10 @@ public void objectFreq() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectIdletime() { + public void objectIdletime(GlideClusterClient clusterClient) { String objectIdletimeKey = "key"; ClusterTransaction transaction = new ClusterTransaction(); transaction.set(objectIdletimeKey, ""); @@ -169,9 +194,10 @@ public void objectIdletime() { assertTrue((long) response[1] >= 0L); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectRefcount() { + public void objectRefcount(GlideClusterClient clusterClient) { String objectRefcountKey = "key"; ClusterTransaction transaction = new ClusterTransaction(); transaction.set(objectRefcountKey, ""); @@ -181,9 +207,10 @@ public void objectRefcount() { assertTrue((long) response[1] >= 0L); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void zrank_zrevrank_withscores() { + public void zrank_zrevrank_withscores(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.2.0")); String zSetKey1 = "{key}:zsetKey1-" + UUID.randomUUID(); ClusterTransaction transaction = new ClusterTransaction(); @@ -197,9 +224,10 @@ public void zrank_zrevrank_withscores() { assertArrayEquals(new Object[] {2L, 1.0}, (Object[]) result[2]); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void watch() { + public void watch(GlideClusterClient clusterClient) { String key1 = "{key}-1" + UUID.randomUUID(); String key2 = "{key}-2" + UUID.randomUUID(); String key3 = "{key}-3" + UUID.randomUUID(); @@ -246,17 +274,17 @@ public void watch() { assertEquals(helloString, clusterClient.get(key2).get()); assertEquals(helloString, clusterClient.get(key3).get()); - // WATCH can not have an empty String array parameter - // Test fails due to https://github.com/amazon-contributing/redis-rs/issues/158 + // https://github.com/valkey-io/valkey-glide/issues/2380 // ExecutionException executionException = // assertThrows(ExecutionException.class, () -> clusterClient.watch(new String[] // {}).get()); // assertInstanceOf(RequestException.class, executionException.getCause()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void unwatch() { + public void unwatch(GlideClusterClient clusterClient) { String key1 = "{key}-1" + UUID.randomUUID(); String key2 = "{key}-2" + UUID.randomUUID(); String foobarString = "foobar"; @@ -279,18 +307,20 @@ public void unwatch() { assertEquals(foobarString, clusterClient.get(key2).get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void spublish() { + public void spublish(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); ClusterTransaction transaction = new ClusterTransaction().publish("messagae", "Schannel", true); assertArrayEquals(new Object[] {0L}, clusterClient.exec(transaction).get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void sort() { + public void sort(GlideClusterClient clusterClient) { String key1 = "{key}:1" + UUID.randomUUID(); String key2 = "{key}:2" + UUID.randomUUID(); String key3 = "{key}:3"; @@ -379,8 +409,9 @@ public void sort() { } @SneakyThrows - @Test - public void waitTest() { + @ParameterizedTest + @MethodSource("getClients") + public void waitTest(GlideClusterClient clusterClient) { // setup String key = UUID.randomUUID().toString(); long numreplicas = 1L; @@ -398,9 +429,10 @@ public void waitTest() { assertTrue((Long) expectedResult[1] <= (Long) results[1]); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_transaction_function_dump_restore() { + public void test_transaction_function_dump_restore(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0")); String libName = "mylib"; String funcName = "myfun"; @@ -424,9 +456,10 @@ public void test_transaction_function_dump_restore() { assertEquals(OK, response[0]); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_transaction_xinfoStream() { + public void test_transaction_xinfoStream(GlideClusterClient clusterClient) { ClusterTransaction transaction = new ClusterTransaction(); final String streamKey = "{streamKey}-" + UUID.randomUUID(); LinkedHashMap expectedStreamInfo = @@ -479,8 +512,9 @@ public void test_transaction_xinfoStream() { } @SneakyThrows - @Test - public void binary_strings() { + @ParameterizedTest + @MethodSource("getClients") + public void binary_strings(GlideClusterClient clusterClient) { String key = UUID.randomUUID().toString(); clusterClient.set(key, "_").get(); // use dump to ensure that we have non-string convertible bytes diff --git a/java/integTest/src/test/java/glide/cluster/CommandTests.java b/java/integTest/src/test/java/glide/cluster/CommandTests.java index cadd37a707..4f56fff903 100644 --- a/java/integTest/src/test/java/glide/cluster/CommandTests.java +++ b/java/integTest/src/test/java/glide/cluster/CommandTests.java @@ -50,6 +50,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Named.named; import glide.api.GlideClusterClient; import glide.api.models.ClusterTransaction; @@ -74,6 +75,7 @@ import glide.api.models.commands.geospatial.GeoUnit; import glide.api.models.commands.scan.ClusterScanCursor; import glide.api.models.commands.scan.ScanOptions; +import glide.api.models.configuration.ProtocolVersion; import glide.api.models.configuration.RequestRoutingConfiguration; import glide.api.models.configuration.RequestRoutingConfiguration.ByAddressRoute; import glide.api.models.configuration.RequestRoutingConfiguration.Route; @@ -98,20 +100,14 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.SneakyThrows; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; @Timeout(10) // seconds public class CommandTests { - private static GlideClusterClient clusterClient = null; - private static final String INITIAL_VALUE = "VALUE"; public static final List DEFAULT_INFO_SECTIONS = @@ -158,23 +154,52 @@ public class CommandTests { "Cluster", "Keyspace"); - @BeforeAll @SneakyThrows - public static void init() { - clusterClient = - GlideClusterClient.createClient(commonClusterClientConfig().requestTimeout(7000).build()) - .get(); - } - - @AfterAll - @SneakyThrows - public static void teardown() { - clusterClient.close(); + public static Stream getClients() { + return Stream.of( + Arguments.of( + named( + "RESP2", + GlideClusterClient.createClient( + commonClusterClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP2) + .build()) + .get())), + Arguments.of( + named( + "RESP3", + GlideClusterClient.createClient( + commonClusterClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP3) + .build()) + .get()))); + } + + private static Stream getTestScenarios() { + return getClients() + .flatMap( + clientArg -> + Stream.of( + Arguments.of(clientArg.get()[0], named("single node route", true)), + Arguments.of(clientArg.get()[0], named("multi node route", false)))); + } + + public static Stream getClientsAndPrefixes() { + return getClients() + .flatMap( + clientArg -> + Stream.of( + Arguments.of(clientArg.get()[0], "abc"), + Arguments.of(clientArg.get()[0], "kln"), + Arguments.of(clientArg.get()[0], "xyz"))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_info() { + public void custom_command_info(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.customCommand(new String[] {"info"}).get(); assertTrue(data.hasMultiData()); for (Object info : data.getMultiValue().values()) { @@ -182,9 +207,10 @@ public void custom_command_info() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_info_binary() { + public void custom_command_info_binary(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.customCommand(new GlideString[] {gs("info")}).get(); assertTrue(data.hasMultiData()); for (Object info : data.getMultiValue().values()) { @@ -193,23 +219,26 @@ public void custom_command_info_binary() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_ping() { + public void custom_command_ping(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.customCommand(new String[] {"ping"}).get(); assertEquals("PONG", data.getSingleValue()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_ping_binary() { + public void custom_command_ping_binary(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.customCommand(new GlideString[] {gs("ping")}).get(); assertEquals(gs("PONG"), data.getSingleValue()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_binary_with_route() { + public void custom_command_binary_with_route(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.customCommand(new GlideString[] {gs("info")}, ALL_NODES).get(); for (Object info : data.getMultiValue().values()) { @@ -222,9 +251,10 @@ public void custom_command_binary_with_route() { assertTrue(data.getSingleValue().toString().contains("# Stats")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_del_returns_a_number() { + public void custom_command_del_returns_a_number(GlideClusterClient clusterClient) { String key = "custom_command_del_returns_a_number"; clusterClient.set(key, INITIAL_VALUE).get(); var del = clusterClient.customCommand(new String[] {"DEL", key}).get(); @@ -233,51 +263,58 @@ public void custom_command_del_returns_a_number() { assertNull(data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping() { + public void ping(GlideClusterClient clusterClient) { String data = clusterClient.ping().get(); assertEquals("PONG", data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_with_message() { + public void ping_with_message(GlideClusterClient clusterClient) { String data = clusterClient.ping("H3LL0").get(); assertEquals("H3LL0", data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_binary_with_message() { + public void ping_binary_with_message(GlideClusterClient clusterClient) { GlideString data = clusterClient.ping(gs("H3LL0")).get(); assertEquals(gs("H3LL0"), data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_with_route() { + public void ping_with_route(GlideClusterClient clusterClient) { String data = clusterClient.ping(ALL_NODES).get(); assertEquals("PONG", data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_with_message_with_route() { + public void ping_with_message_with_route(GlideClusterClient clusterClient) { String data = clusterClient.ping("H3LL0", ALL_PRIMARIES).get(); assertEquals("H3LL0", data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_binary_with_message_with_route() { + public void ping_binary_with_message_with_route(GlideClusterClient clusterClient) { GlideString data = clusterClient.ping(gs("H3LL0"), ALL_PRIMARIES).get(); assertEquals(gs("H3LL0"), data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_without_options() { + public void info_without_options(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.info().get(); assertTrue(data.hasMultiData()); for (String info : data.getMultiValue().values()) { @@ -287,9 +324,10 @@ public void info_without_options() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_single_node_route() { + public void info_with_single_node_route(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.info(RANDOM).get(); assertTrue(data.hasSingleData()); String infoData = data.getSingleValue(); @@ -298,9 +336,10 @@ public void info_with_single_node_route() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_multi_node_route() { + public void info_with_multi_node_route(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.info(ALL_NODES).get(); assertTrue(data.hasMultiData()); for (String info : data.getMultiValue().values()) { @@ -310,9 +349,10 @@ public void info_with_multi_node_route() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_multiple_options() { + public void info_with_multiple_options(GlideClusterClient clusterClient) { Section[] sections = {CLUSTER}; if (SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0")) { sections = concatenateArrays(sections, new Section[] {CPU, MEMORY}); @@ -327,9 +367,10 @@ public void info_with_multiple_options() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_everything_option() { + public void info_with_everything_option(GlideClusterClient clusterClient) { ClusterValue data = clusterClient.info(new Section[] {EVERYTHING}).get(); assertTrue(data.hasMultiData()); for (String info : data.getMultiValue().values()) { @@ -339,9 +380,10 @@ public void info_with_everything_option() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_single_node_route_and_options() { + public void info_with_single_node_route_and_options(GlideClusterClient clusterClient) { ClusterValue slotData = clusterClient.customCommand(new String[] {"cluster", "slots"}).get(); @@ -370,9 +412,10 @@ public void info_with_single_node_route_and_options() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_multi_node_route_and_options() { + public void info_with_multi_node_route_and_options(GlideClusterClient clusterClient) { Section[] sections = {CLIENTS}; if (SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0")) { sections = concatenateArrays(sections, new Section[] {COMMANDSTATS, REPLICATION}); @@ -388,30 +431,34 @@ public void info_with_multi_node_route_and_options() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientId() { + public void clientId(GlideClusterClient clusterClient) { var id = clusterClient.clientId().get(); assertTrue(id > 0); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientId_with_single_node_route() { + public void clientId_with_single_node_route(GlideClusterClient clusterClient) { var data = clusterClient.clientId(RANDOM).get(); assertTrue(data.getSingleValue() > 0L); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientId_with_multi_node_route() { + public void clientId_with_multi_node_route(GlideClusterClient clusterClient) { var data = clusterClient.clientId(ALL_NODES).get(); data.getMultiValue().values().forEach(id -> assertTrue(id > 0)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientGetName() { + public void clientGetName(GlideClusterClient clusterClient) { // TODO replace with the corresponding command once implemented clusterClient.customCommand(new String[] {"client", "setname", "clientGetName"}).get(); @@ -420,9 +467,10 @@ public void clientGetName() { assertEquals("clientGetName", name); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientGetName_with_single_node_route() { + public void clientGetName_with_single_node_route(GlideClusterClient clusterClient) { // TODO replace with the corresponding command once implemented clusterClient .customCommand( @@ -434,9 +482,10 @@ public void clientGetName_with_single_node_route() { assertEquals("clientGetName_with_single_node_route", name.getSingleValue()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientGetName_with_multi_node_route() { + public void clientGetName_with_multi_node_route(GlideClusterClient clusterClient) { // TODO replace with the corresponding command once implemented clusterClient .customCommand( @@ -448,9 +497,10 @@ public void clientGetName_with_multi_node_route() { assertEquals("clientGetName_with_multi_node_route", getFirstEntryFromMultiValue(name)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void config_reset_stat() { + public void config_reset_stat(GlideClusterClient clusterClient) { var data = clusterClient.info(new Section[] {STATS}).get(); String firstNodeInfo = getFirstEntryFromMultiValue(data); long value_before = getValueFromInfo(firstNodeInfo, "total_net_input_bytes"); @@ -464,9 +514,10 @@ public void config_reset_stat() { assertTrue(value_after < value_before); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void config_rewrite_non_existent_config_file() { + public void config_rewrite_non_existent_config_file(GlideClusterClient clusterClient) { var info = clusterClient.info(new Section[] {SERVER}, RANDOM).get(); var configFile = parseInfoResponseToMap(info.getSingleValue()).get("config_file"); @@ -489,27 +540,30 @@ private String cleanResult(String value) { .orElse(null); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configGet_with_no_args_returns_error() { + public void configGet_with_no_args_returns_error(GlideClusterClient clusterClient) { var exception = assertThrows( ExecutionException.class, () -> clusterClient.configGet(new String[] {}).get()); assertTrue(exception.getCause() instanceof GlideException); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configGet_with_wildcard() { + public void configGet_with_wildcard(GlideClusterClient clusterClient) { var data = clusterClient.configGet(new String[] {"*file"}).get(); assertTrue(data.size() > 5); assertTrue(data.containsKey("pidfile")); assertTrue(data.containsKey("logfile")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configGet_with_multiple_params() { + public void configGet_with_multiple_params(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); var data = clusterClient.configGet(new String[] {"pidfile", "logfile"}).get(); assertAll( @@ -518,9 +572,10 @@ public void configGet_with_multiple_params() { () -> assertTrue(data.containsKey("logfile"))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configGet_with_wildcard_and_multi_node_route() { + public void configGet_with_wildcard_and_multi_node_route(GlideClusterClient clusterClient) { var data = clusterClient.configGet(new String[] {"*file"}, ALL_PRIMARIES).get(); assertTrue(data.hasMultiData()); assertTrue(data.getMultiValue().size() > 1); @@ -532,9 +587,10 @@ public void configGet_with_wildcard_and_multi_node_route() { () -> assertTrue(config.containsKey("logfile"))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configSet_a_parameter() { + public void configSet_a_parameter(GlideClusterClient clusterClient) { var oldValue = clusterClient.configGet(new String[] {"maxclients"}).get().get("maxclients"); var response = clusterClient.configSet(Map.of("maxclients", "42")).get(); @@ -546,9 +602,10 @@ public void configSet_a_parameter() { assertEquals(OK, response); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configSet_a_parameter_with_routing() { + public void configSet_a_parameter_with_routing(GlideClusterClient clusterClient) { var oldValue = clusterClient .configGet(new String[] {"cluster-node-timeout"}) @@ -566,9 +623,10 @@ public void configSet_a_parameter_with_routing() { assertEquals(OK, response); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void cluster_route_by_address_reaches_correct_node() { + public void cluster_route_by_address_reaches_correct_node(GlideClusterClient clusterClient) { // Masks timestamps in the cluster nodes output to avoid flakiness due to dynamic values. String initialNode = cleanResult( @@ -603,23 +661,27 @@ public void cluster_route_by_address_reaches_correct_node() { assertEquals(initialNode, specifiedClusterNode2); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void cluster_fail_routing_by_address_if_no_port_is_provided() { + public void cluster_fail_routing_by_address_if_no_port_is_provided( + GlideClusterClient clusterClient) { assertThrows(RequestException.class, () -> clusterClient.info(new ByAddressRoute("foo")).get()); } @SneakyThrows - @Test - public void echo() { + @ParameterizedTest + @MethodSource("getClients") + public void echo(GlideClusterClient clusterClient) { String message = "GLIDE"; String response = clusterClient.echo(message).get(); assertEquals(message, response); } @SneakyThrows - @Test - public void echo_with_route() { + @ParameterizedTest + @MethodSource("getClients") + public void echo_with_route(GlideClusterClient clusterClient) { String message = "GLIDE"; String singlePayload = clusterClient.echo(message, RANDOM).get().getSingleValue(); @@ -630,16 +692,18 @@ public void echo_with_route() { } @SneakyThrows - @Test - public void echo_gs() { + @ParameterizedTest + @MethodSource("getClients") + public void echo_gs(GlideClusterClient clusterClient) { byte[] message = {(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02}; GlideString response = clusterClient.echo(gs(message)).get(); assertEquals(gs(message), response); } @SneakyThrows - @Test - public void echo_gs_with_route() { + @ParameterizedTest + @MethodSource("getClients") + public void echo_gs_with_route(GlideClusterClient clusterClient) { byte[] message = {(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02}; GlideString singlePayload = clusterClient.echo(gs(message), RANDOM).get().getSingleValue(); assertEquals(gs(message), singlePayload); @@ -649,9 +713,10 @@ public void echo_gs_with_route() { multiPayload.forEach((key, value) -> assertEquals(gs(message), value)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void time() { + public void time(GlideClusterClient clusterClient) { // Take the time now, convert to 10 digits and subtract 1 second long now = Instant.now().getEpochSecond() - 1L; String[] result = clusterClient.time().get(); @@ -662,9 +727,10 @@ public void time() { assertTrue(Long.parseLong(result[1]) < 1000000); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void time_with_route() { + public void time_with_route(GlideClusterClient clusterClient) { // Take the time now, convert to 10 digits and subtract 1 second long now = Instant.now().getEpochSecond() - 1L; @@ -683,9 +749,10 @@ public void time_with_route() { assertTrue(Long.parseLong((String) serverTime[1]) < 1000000); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void lastsave() { + public void lastsave(GlideClusterClient clusterClient) { long result = clusterClient.lastsave().get(); var yesterday = Instant.now().minus(1, ChronoUnit.DAYS); @@ -697,9 +764,10 @@ public void lastsave() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void lolwut_lolwut() { + public void lolwut_lolwut(GlideClusterClient clusterClient) { var response = clusterClient.lolwut().get(); System.out.printf("%nLOLWUT cluster client standard response%n%s%n", response); assertTrue(response.contains("Redis ver. " + SERVER_VERSION)); @@ -734,9 +802,10 @@ public void lolwut_lolwut() { assertTrue(clusterResponse.getSingleValue().contains("Redis ver. " + SERVER_VERSION)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void dbsize_and_flushdb() { + public void dbsize_and_flushdb(GlideClusterClient clusterClient) { boolean is62orHigher = SERVER_VERSION.isGreaterThanOrEqualTo("6.2.0"); assertEquals(OK, clusterClient.flushall().get()); @@ -788,9 +857,10 @@ public void dbsize_and_flushdb() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectFreq() { + public void objectFreq(GlideClusterClient clusterClient) { String key = UUID.randomUUID().toString(); String maxmemoryPolicy = "maxmemory-policy"; String oldPolicy = @@ -804,7 +874,9 @@ public void objectFreq() { } } + @SneakyThrows public static Stream callCrossSlotCommandsWhichShouldFail() { + var clusterClient = GlideClusterClient.createClient(commonClusterClientConfig().build()).get(); return Stream.of( Arguments.of("smove", null, clusterClient.smove("abc", "zxy", "lkn")), Arguments.of("rename", null, clusterClient.rename("abc", "xyz")), @@ -1010,7 +1082,9 @@ public void check_throws_cross_slot_error( assertTrue(executionException.getMessage().toLowerCase().contains("crossslot")); } + @SneakyThrows public static Stream callCrossSlotCommandsWhichShouldPass() { + var clusterClient = GlideClusterClient.createClient(commonClusterClientConfig().build()).get(); return Stream.of( Arguments.of("exists", clusterClient.exists(new String[] {"abc", "zxy", "lkn"})), Arguments.of("unlink", clusterClient.unlink(new String[] {"abc", "zxy", "lkn"})), @@ -1031,9 +1105,10 @@ public void check_does_not_throw_cross_slot_error(String testName, CompletableFu future.get(); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void flushall() { + public void flushall(GlideClusterClient clusterClient) { if (SERVER_VERSION.isGreaterThanOrEqualTo("6.2.0")) { assertEquals(OK, clusterClient.flushall(SYNC).get()); } else { @@ -1071,11 +1146,11 @@ public void flushall() { } } - // TODO: add a binary version of this test @SneakyThrows - @ParameterizedTest(name = "functionLoad: singleNodeRoute = {0}") - @ValueSource(booleans = {true, false}) - public void function_commands_without_keys_with_route(boolean singleNodeRoute) { + @ParameterizedTest + @MethodSource("getTestScenarios") + public void function_commands_without_keys_with_route( + GlideClusterClient clusterClient, boolean singleNodeRoute) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "mylib1c_" + singleNodeRoute; @@ -1221,11 +1296,11 @@ public void function_commands_without_keys_with_route(boolean singleNodeRoute) { assertEquals(OK, clusterClient.functionFlush(route).get()); } - // TODO: add a binary version of this test @SneakyThrows - @ParameterizedTest(name = "functionLoad: singleNodeRoute = {0}") - @ValueSource(booleans = {true, false}) - public void function_commands_without_keys_with_route_binary(boolean singleNodeRoute) { + @ParameterizedTest + @MethodSource("getTestScenarios") + public void function_commands_without_keys_with_route_binary( + GlideClusterClient clusterClient, boolean singleNodeRoute) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("mylib1c_" + singleNodeRoute); @@ -1381,8 +1456,9 @@ public void function_commands_without_keys_with_route_binary(boolean singleNodeR } @SneakyThrows - @Test - public void function_commands_without_keys_and_without_route() { + @ParameterizedTest + @MethodSource("getClients") + public void function_commands_without_keys_and_without_route(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assertEquals(OK, clusterClient.functionFlush(SYNC).get()); @@ -1464,8 +1540,10 @@ public void function_commands_without_keys_and_without_route() { } @SneakyThrows - @Test - public void function_commands_without_keys_and_without_route_binary() { + @ParameterizedTest + @MethodSource("getClients") + public void function_commands_without_keys_and_without_route_binary( + GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assertEquals(OK, clusterClient.functionFlush(SYNC).get()); @@ -1557,9 +1635,9 @@ public void function_commands_without_keys_and_without_route_binary() { } @ParameterizedTest - @ValueSource(strings = {"abc", "xyz", "kln"}) + @MethodSource("getClientsAndPrefixes") @SneakyThrows - public void fcall_with_keys(String prefix) { + public void fcall_with_keys(GlideClusterClient clusterClient, String prefix) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String key = "{" + prefix + "}-fcall_with_keys-"; @@ -1598,9 +1676,9 @@ public void fcall_with_keys(String prefix) { } @ParameterizedTest - @ValueSource(strings = {"abc", "xyz", "kln"}) + @MethodSource("getClientsAndPrefixes") @SneakyThrows - public void fcall_binary_with_keys(String prefix) { + public void fcall_binary_with_keys(GlideClusterClient clusterClient, String prefix) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String key = "{" + prefix + "}-fcall_with_keys-"; @@ -1646,8 +1724,9 @@ public void fcall_binary_with_keys(String prefix) { } @SneakyThrows - @Test - public void fcall_readonly_function() { + @ParameterizedTest + @MethodSource("getClients") + public void fcall_readonly_function(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assumeTrue( !SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), @@ -1704,8 +1783,9 @@ public void fcall_readonly_function() { } @SneakyThrows - @Test - public void fcall_readonly_binary_function() { + @ParameterizedTest + @MethodSource("getClients") + public void fcall_readonly_binary_function(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assumeTrue( !SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), @@ -1762,9 +1842,10 @@ public void fcall_readonly_binary_function() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKill_no_write_without_route() { + public void functionKill_no_write_without_route(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "functionKill_no_write_without_route"; @@ -1816,9 +1897,10 @@ public void functionKill_no_write_without_route() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKillBinary_no_write_without_route() { + public void functionKillBinary_no_write_without_route(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("functionKillBinary_no_write_without_route"); @@ -1871,10 +1953,11 @@ public void functionKillBinary_no_write_without_route() { } @Timeout(20) - @ParameterizedTest(name = "single node route = {0}") - @ValueSource(booleans = {true, false}) + @ParameterizedTest + @MethodSource("getTestScenarios") @SneakyThrows - public void functionKill_no_write_with_route(boolean singleNodeRoute) { + public void functionKill_no_write_with_route( + GlideClusterClient clusterClient, boolean singleNodeRoute) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "functionKill_no_write_with_route" + singleNodeRoute; @@ -1923,10 +2006,11 @@ public void functionKill_no_write_with_route(boolean singleNodeRoute) { } @Timeout(20) - @ParameterizedTest(name = "single node route = {0}") - @ValueSource(booleans = {true, false}) + @ParameterizedTest + @MethodSource("getTestScenarios") @SneakyThrows - public void functionKillBinary_no_write_with_route(boolean singleNodeRoute) { + public void functionKillBinary_no_write_with_route( + GlideClusterClient clusterClient, boolean singleNodeRoute) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("functionKillBinary_no_write_with_route" + singleNodeRoute); @@ -1977,9 +2061,10 @@ public void functionKillBinary_no_write_with_route(boolean singleNodeRoute) { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKill_key_based_write_function() { + public void functionKill_key_based_write_function(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "functionKill_key_based_write_function"; @@ -2043,9 +2128,10 @@ public void functionKill_key_based_write_function() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKillBinary_key_based_write_function() { + public void functionKillBinary_key_based_write_function(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("functionKillBinary_key_based_write_function"); @@ -2110,9 +2196,10 @@ public void functionKillBinary_key_based_write_function() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionStats_without_route() { + public void functionStats_without_route(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "functionStats_without_route"; @@ -2148,9 +2235,10 @@ public void functionStats_without_route() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionStatsBinary_without_route() { + public void functionStatsBinary_without_route(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("functionStats_without_route"); @@ -2191,10 +2279,10 @@ public void functionStatsBinary_without_route() { } } - @ParameterizedTest(name = "single node route = {0}") - @ValueSource(booleans = {true, false}) + @ParameterizedTest + @MethodSource("getTestScenarios") @SneakyThrows - public void functionStats_with_route(boolean singleNodeRoute) { + public void functionStats_with_route(GlideClusterClient clusterClient, boolean singleNodeRoute) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); Route route = singleNodeRoute ? new SlotKeyRoute(UUID.randomUUID().toString(), PRIMARY) : ALL_PRIMARIES; @@ -2244,10 +2332,11 @@ public void functionStats_with_route(boolean singleNodeRoute) { } } - @ParameterizedTest(name = "single node route = {0}") - @ValueSource(booleans = {true, false}) + @ParameterizedTest + @MethodSource("getTestScenarios") @SneakyThrows - public void functionStatsBinary_with_route(boolean singleNodeRoute) { + public void functionStatsBinary_with_route( + GlideClusterClient clusterClient, boolean singleNodeRoute) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); Route route = singleNodeRoute ? new SlotKeyRoute(UUID.randomUUID().toString(), PRIMARY) : ALL_PRIMARIES; @@ -2303,9 +2392,10 @@ public void functionStatsBinary_with_route(boolean singleNodeRoute) { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void function_dump_and_restore() { + public void function_dump_and_restore(GlideClusterClient clusterClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assertEquals(OK, clusterClient.functionFlush(SYNC).get()); @@ -2385,9 +2475,10 @@ public void function_dump_and_restore() { 2L, clusterClient.fcallReadOnly(name2, new String[0], new String[] {"meow", "woem"}).get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void randomKey() { + public void randomKey(GlideClusterClient clusterClient) { String key1 = "{key}" + UUID.randomUUID(); String key2 = "{key}" + UUID.randomUUID(); @@ -2407,9 +2498,10 @@ public void randomKey() { assertNull(clusterClient.randomKey().get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void randomKeyBinary() { + public void randomKeyBinary(GlideClusterClient clusterClient) { GlideString key1 = gs("{key}" + UUID.randomUUID()); GlideString key2 = gs("{key}" + UUID.randomUUID()); @@ -2429,9 +2521,10 @@ public void randomKeyBinary() { assertNull(clusterClient.randomKey().get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void sort() { + public void sort(GlideClusterClient clusterClient) { String key1 = "{key}-1" + UUID.randomUUID(); String key2 = "{key}-2" + UUID.randomUUID(); String key3 = "{key}-3" + UUID.randomUUID(); @@ -2510,9 +2603,10 @@ public void sort() { assertArrayEquals(key2DescendingListSubset, clusterClient.lrange(key3, 0, -1).get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void sort_binary() { + public void sort_binary(GlideClusterClient clusterClient) { GlideString key1 = gs("{key}-1" + UUID.randomUUID()); GlideString key2 = gs("{key}-2" + UUID.randomUUID()); GlideString key3 = gs("{key}-3" + UUID.randomUUID()); @@ -2603,9 +2697,10 @@ public void sort_binary() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_simple() { + public void test_cluster_scan_simple(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); String key = "key:test_cluster_scan_simple" + UUID.randomUUID(); @@ -2634,9 +2729,10 @@ public void test_cluster_scan_simple() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_binary_simple() { + public void test_cluster_scan_binary_simple(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); String key = "key:test_cluster_scan_simple" + UUID.randomUUID(); @@ -2665,9 +2761,10 @@ public void test_cluster_scan_binary_simple() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_with_object_type_and_pattern() { + public void test_cluster_scan_with_object_type_and_pattern(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); String key = "key:" + UUID.randomUUID(); Map expectedData = new LinkedHashMap<>(); @@ -2722,9 +2819,10 @@ public void test_cluster_scan_with_object_type_and_pattern() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_with_count() { + public void test_cluster_scan_with_count(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); String key = "key:" + UUID.randomUUID(); Map expectedData = new LinkedHashMap<>(); @@ -2771,9 +2869,10 @@ public void test_cluster_scan_with_count() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_with_match() { + public void test_cluster_scan_with_match(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); String key = "key:" + UUID.randomUUID(); Map expectedData = new LinkedHashMap<>(); @@ -2805,9 +2904,10 @@ public void test_cluster_scan_with_match() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_cleaning_cursor() { + public void test_cluster_scan_cleaning_cursor(GlideClusterClient clusterClient) { // We test whether the cursor is cleaned up after it is deleted, which we expect to happen when // the GC is called. assertEquals(OK, clusterClient.flushall().get()); @@ -2831,9 +2931,10 @@ public void test_cluster_scan_cleaning_cursor() { assertTrue(exception.getCause().getMessage().contains("Invalid scan_state_cursor id")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_all_strings() { + public void test_cluster_scan_all_strings(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); String key = "key:" + UUID.randomUUID(); @@ -2860,9 +2961,10 @@ public void test_cluster_scan_all_strings() { assertEquals(stringData.keySet(), results); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_all_set() { + public void test_cluster_scan_all_set(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); final int baseNumberOfEntries = 5; @@ -2891,9 +2993,10 @@ public void test_cluster_scan_all_set() { assertEquals(setData.keySet(), results); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_all_hash() { + public void test_cluster_scan_all_hash(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); final int baseNumberOfEntries = 5; @@ -2922,9 +3025,10 @@ public void test_cluster_scan_all_hash() { assertEquals(hashData.keySet(), results); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_all_list() { + public void test_cluster_scan_all_list(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); final int baseNumberOfEntries = 5; @@ -2953,9 +3057,10 @@ public void test_cluster_scan_all_list() { assertEquals(listData.keySet(), results); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_all_sorted_set() { + public void test_cluster_scan_all_sorted_set(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); final int baseNumberOfEntries = 5; @@ -2985,9 +3090,10 @@ public void test_cluster_scan_all_sorted_set() { assertEquals(zSetData.keySet(), results); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_cluster_scan_all_stream() { + public void test_cluster_scan_all_stream(GlideClusterClient clusterClient) { assertEquals(OK, clusterClient.flushall().get()); final int baseNumberOfEntries = 5; @@ -3018,8 +3124,9 @@ public void test_cluster_scan_all_stream() { } @SneakyThrows - @Test - public void invokeScript_test() { + @ParameterizedTest + @MethodSource("getClients") + public void invokeScript_test(GlideClusterClient clusterClient) { String key1 = UUID.randomUUID().toString(); String key2 = UUID.randomUUID().toString(); @@ -3057,8 +3164,9 @@ public void invokeScript_test() { } @SneakyThrows - @Test - public void script_large_keys_and_or_args() { + @ParameterizedTest + @MethodSource("getClients") + public void script_large_keys_and_or_args(GlideClusterClient clusterClient) { String str1 = "0".repeat(1 << 12); // 4k String str2 = "0".repeat(1 << 12); // 4k @@ -3100,8 +3208,9 @@ public void script_large_keys_and_or_args() { } @SneakyThrows - @Test - public void invokeScript_gs_test() { + @ParameterizedTest + @MethodSource("getClients") + public void invokeScript_gs_test(GlideClusterClient clusterClient) { GlideString key1 = gs(UUID.randomUUID().toString()); GlideString key2 = gs(UUID.randomUUID().toString()); @@ -3142,9 +3251,10 @@ public void invokeScript_gs_test() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scriptExists() { + public void scriptExists(GlideClusterClient clusterClient) { Script script1 = new Script("return 'Hello'", true); Script script2 = new Script("return 'World'", true); Script script3 = new Script("return 'Hello World'", true); @@ -3173,9 +3283,10 @@ public void scriptExists() { assertArrayEquals(expected, result2); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scriptExistsBinary() { + public void scriptExistsBinary(GlideClusterClient clusterClient) { Script script1 = new Script(gs("return 'Hello'"), true); Script script2 = new Script(gs("return 'World'"), true); Script script3 = new Script(gs("return 'Hello World'"), true); @@ -3206,9 +3317,10 @@ public void scriptExistsBinary() { assertArrayEquals(expected, result2); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scriptFlush() { + public void scriptFlush(GlideClusterClient clusterClient) { Script script = new Script("return 'Hello'", true); // Load script @@ -3233,9 +3345,10 @@ public void scriptFlush() { assertArrayEquals(new Boolean[] {false}, result); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scriptKill_with_route() { + public void scriptKill_with_route(GlideClusterClient clusterClient) { // create and load a long-running script and a primary node route Script script = new Script(createLongRunningLuaScript(5, true), true); RequestRoutingConfiguration.Route route = @@ -3294,8 +3407,9 @@ public void scriptKill_with_route() { } @SneakyThrows - @Test - public void scriptKill_unkillable() { + @ParameterizedTest + @MethodSource("getClients") + public void scriptKill_unkillable(GlideClusterClient clusterClient) { String key = UUID.randomUUID().toString(); RequestRoutingConfiguration.Route route = new RequestRoutingConfiguration.SlotKeyRoute(key, PRIMARY); diff --git a/java/integTest/src/test/java/glide/standalone/CommandTests.java b/java/integTest/src/test/java/glide/standalone/CommandTests.java index 5e558a0273..1887513ba4 100644 --- a/java/integTest/src/test/java/glide/standalone/CommandTests.java +++ b/java/integTest/src/test/java/glide/standalone/CommandTests.java @@ -44,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Named.named; import glide.api.GlideClient; import glide.api.models.GlideString; @@ -53,6 +54,7 @@ import glide.api.models.commands.ScriptOptions; import glide.api.models.commands.ScriptOptionsGlideString; import glide.api.models.commands.scan.ScanOptions; +import glide.api.models.configuration.ProtocolVersion; import glide.api.models.exceptions.RequestException; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -65,58 +67,63 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; import lombok.SneakyThrows; import org.apache.commons.lang3.ArrayUtils; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; @Timeout(10) // seconds public class CommandTests { private static final String INITIAL_VALUE = "VALUE"; - private static GlideClient regularClient = null; - - @BeforeAll - @SneakyThrows - public static void init() { - regularClient = - GlideClient.createClient(commonClientConfig().requestTimeout(7000).build()).get(); - } - - @AfterAll - @SneakyThrows - public static void teardown() { - regularClient.close(); - } - - @AfterEach @SneakyThrows - public void cleanup() { - regularClient.flushall().get(); + public static Stream getClients() { + return Stream.of( + Arguments.of( + named( + "RESP2", + GlideClient.createClient( + commonClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP2) + .build()) + .get())), + Arguments.of( + named( + "RESP3", + GlideClient.createClient( + commonClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP3) + .build()) + .get()))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_info() { + public void custom_command_info(GlideClient regularClient) { Object data = regularClient.customCommand(new String[] {"info"}).get(); assertTrue(((String) data).contains("# Stats")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_info_binary() { + public void custom_command_info_binary(GlideClient regularClient) { Object data = regularClient.customCommand(new GlideString[] {gs("info")}).get(); assertInstanceOf(GlideString.class, data); assertTrue(data.toString().contains("# Stats")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_del_returns_a_number() { + public void custom_command_del_returns_a_number(GlideClient regularClient) { String key = "custom_command_del_returns_a_number"; regularClient.set(key, INITIAL_VALUE).get(); var del = regularClient.customCommand(new String[] {"DEL", key}).get(); @@ -125,39 +132,44 @@ public void custom_command_del_returns_a_number() { assertNull(data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping() { + public void ping(GlideClient regularClient) { String data = regularClient.ping().get(); assertEquals("PONG", data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_with_message() { + public void ping_with_message(GlideClient regularClient) { String data = regularClient.ping("H3LL0").get(); assertEquals("H3LL0", data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_binary_with_message() { + public void ping_binary_with_message(GlideClient regularClient) { GlideString data = regularClient.ping(gs("H3LL0")).get(); assertEquals(gs("H3LL0"), data); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_without_options() { + public void info_without_options(GlideClient regularClient) { String data = regularClient.info().get(); for (String section : DEFAULT_INFO_SECTIONS) { assertTrue(data.contains("# " + section), "Section " + section + " is missing"); } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_multiple_options() { + public void info_with_multiple_options(GlideClient regularClient) { Section[] sections = {CLUSTER}; if (SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0")) { sections = concatenateArrays(sections, new Section[] {CPU, MEMORY}); @@ -170,18 +182,20 @@ public void info_with_multiple_options() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_with_everything_option() { + public void info_with_everything_option(GlideClient regularClient) { String data = regularClient.info(new Section[] {EVERYTHING}).get(); for (String section : EVERYTHING_INFO_SECTIONS) { assertTrue(data.contains("# " + section), "Section " + section + " is missing"); } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void simple_select_test() { + public void simple_select_test(GlideClient regularClient) { assertEquals(OK, regularClient.select(0).get()); String key = UUID.randomUUID().toString(); @@ -195,17 +209,19 @@ public void simple_select_test() { assertEquals(value, regularClient.get(key).get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void select_test_gives_error() { + public void select_test_gives_error(GlideClient regularClient) { ExecutionException e = assertThrows(ExecutionException.class, () -> regularClient.select(-1).get()); assertTrue(e.getCause() instanceof RequestException); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void move() { + public void move(GlideClient regularClient) { String key1 = UUID.randomUUID().toString(); String key2 = UUID.randomUUID().toString(); String value1 = UUID.randomUUID().toString(); @@ -233,9 +249,10 @@ public void move() { assertTrue(e.getCause() instanceof RequestException); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void move_binary() { + public void move_binary(GlideClient regularClient) { GlideString key1 = gs(UUID.randomUUID().toString()); GlideString key2 = gs(UUID.randomUUID().toString()); GlideString value1 = gs(UUID.randomUUID().toString()); @@ -263,16 +280,18 @@ public void move_binary() { assertTrue(e.getCause() instanceof RequestException); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientId() { + public void clientId(GlideClient regularClient) { var id = regularClient.clientId().get(); assertTrue(id > 0); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void clientGetName() { + public void clientGetName(GlideClient regularClient) { // TODO replace with the corresponding command once implemented regularClient.customCommand(new String[] {"client", "setname", "clientGetName"}).get(); @@ -281,9 +300,10 @@ public void clientGetName() { assertEquals("clientGetName", name); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void config_reset_stat() { + public void config_reset_stat(GlideClient regularClient) { String data = regularClient.info(new Section[] {STATS}).get(); long value_before = getValueFromInfo(data, "total_net_input_bytes"); @@ -295,9 +315,10 @@ public void config_reset_stat() { assertTrue(value_after < value_before); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void config_rewrite_non_existent_config_file() { + public void config_rewrite_non_existent_config_file(GlideClient regularClient) { var info = regularClient.info(new Section[] {SERVER}).get(); var configFile = parseInfoResponseToMap(info).get("config_file"); @@ -310,9 +331,10 @@ public void config_rewrite_non_existent_config_file() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configGet_with_no_args_returns_error() { + public void configGet_with_no_args_returns_error(GlideClient regularClient) { var exception = assertThrows( ExecutionException.class, () -> regularClient.configGet(new String[] {}).get()); @@ -320,18 +342,20 @@ public void configGet_with_no_args_returns_error() { assertTrue(exception.getCause().getMessage().contains("wrong number of arguments")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configGet_with_wildcard() { + public void configGet_with_wildcard(GlideClient regularClient) { var data = regularClient.configGet(new String[] {"*file"}).get(); assertTrue(data.size() > 5); assertTrue(data.containsKey("pidfile")); assertTrue(data.containsKey("logfile")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configGet_with_multiple_params() { + public void configGet_with_multiple_params(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); var data = regularClient.configGet(new String[] {"pidfile", "logfile"}).get(); assertAll( @@ -340,9 +364,10 @@ public void configGet_with_multiple_params() { () -> assertTrue(data.containsKey("logfile"))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configSet_with_unknown_parameter_returns_error() { + public void configSet_with_unknown_parameter_returns_error(GlideClient regularClient) { var exception = assertThrows( ExecutionException.class, @@ -350,9 +375,10 @@ public void configSet_with_unknown_parameter_returns_error() { assertTrue(exception.getCause() instanceof RequestException); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void configSet_a_parameter() { + public void configSet_a_parameter(GlideClient regularClient) { var oldValue = regularClient.configGet(new String[] {"maxclients"}).get().get("maxclients"); var response = regularClient.configSet(Map.of("maxclients", "42")).get(); @@ -365,8 +391,9 @@ public void configSet_a_parameter() { } @SneakyThrows - @Test - public void echo() { + @ParameterizedTest + @MethodSource("getClients") + public void echo(GlideClient regularClient) { String message = "GLIDE"; String response = regularClient.echo(message).get(); assertEquals(message, response); @@ -376,16 +403,18 @@ public void echo() { } @SneakyThrows - @Test - public void echo_gs() { + @ParameterizedTest + @MethodSource("getClients") + public void echo_gs(GlideClient regularClient) { byte[] message = {(byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02}; GlideString response = regularClient.echo(gs(message)).get(); assertEquals(gs(message), response); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void time() { + public void time(GlideClient regularClient) { // Take the time now, convert to 10 digits and subtract 1 second long now = Instant.now().getEpochSecond() - 1L; String[] result = regularClient.time().get(); @@ -398,17 +427,19 @@ public void time() { assertTrue(Long.parseLong(result[1]) < 1000000); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void lastsave() { + public void lastsave(GlideClient regularClient) { long result = regularClient.lastsave().get(); var yesterday = Instant.now().minus(1, ChronoUnit.DAYS); assertTrue(Instant.ofEpochSecond(result).isAfter(yesterday)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void lolwut_lolwut() { + public void lolwut_lolwut(GlideClient regularClient) { var response = regularClient.lolwut().get(); System.out.printf("%nLOLWUT standalone client standard response%n%s%n", response); assertTrue(response.contains("Redis ver. " + SERVER_VERSION)); @@ -428,9 +459,10 @@ public void lolwut_lolwut() { assertTrue(response.contains("Redis ver. " + SERVER_VERSION)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void dbsize_and_flushdb() { + public void dbsize_and_flushdb(GlideClient regularClient) { assertEquals(OK, regularClient.flushall().get()); assertEquals(OK, regularClient.select(0).get()); @@ -467,9 +499,10 @@ public void dbsize_and_flushdb() { assertEquals(0L, regularClient.dbsize().get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectFreq() { + public void objectFreq(GlideClient regularClient) { String key = UUID.randomUUID().toString(); String maxmemoryPolicy = "maxmemory-policy"; String oldPolicy = @@ -483,9 +516,10 @@ public void objectFreq() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void flushall() { + public void flushall(GlideClient regularClient) { if (SERVER_VERSION.isGreaterThanOrEqualTo("6.2.0")) { assertEquals(OK, regularClient.flushall(SYNC).get()); } else { @@ -504,8 +538,9 @@ public void flushall() { } @SneakyThrows - @Test - public void function_commands() { + @ParameterizedTest + @MethodSource("getClients") + public void function_commands(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assertEquals(OK, regularClient.functionFlush(SYNC).get()); @@ -591,8 +626,9 @@ public void function_commands() { } @SneakyThrows - @Test - public void function_commands_binary() { + @ParameterizedTest + @MethodSource("getClients") + public void function_commands_binary(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assertEquals(OK, regularClient.functionFlush(SYNC).get()); @@ -690,9 +726,10 @@ public void function_commands_binary() { assertEquals(OK, regularClient.functionFlush(ASYNC).get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void copy() { + public void copy(GlideClient regularClient) { assumeTrue( SERVER_VERSION.isGreaterThanOrEqualTo("6.2.0"), "This feature added in version 6.2.0"); // setup @@ -740,9 +777,10 @@ public void copy() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKill_no_write() { + public void functionKill_no_write(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "functionKill_no_write"; @@ -790,9 +828,10 @@ public void functionKill_no_write() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKillBinary_no_write() { + public void functionKillBinary_no_write(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("functionKillBinary_no_write"); @@ -841,9 +880,10 @@ public void functionKillBinary_no_write() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKill_write_function() { + public void functionKill_write_function(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "functionKill_write_function"; @@ -906,9 +946,10 @@ public void functionKill_write_function() { } @Timeout(20) - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionKillBinary_write_function() { + public void functionKillBinary_write_function(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("functionKill_write_function"); @@ -971,9 +1012,10 @@ public void functionKillBinary_write_function() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionStats() { + public void functionStats(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); String libName = "functionStats"; @@ -1009,9 +1051,10 @@ public void functionStats() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void functionStatsBinary() { + public void functionStatsBinary(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); GlideString libName = gs("functionStats"); @@ -1052,9 +1095,10 @@ public void functionStatsBinary() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void function_dump_and_restore() { + public void function_dump_and_restore(GlideClient regularClient) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assertEquals(OK, regularClient.functionFlush(SYNC).get()); @@ -1120,8 +1164,9 @@ public void function_dump_and_restore() { } @SneakyThrows - @Test - public void randomkey() { + @ParameterizedTest + @MethodSource("getClients") + public void randomkey(GlideClient regularClient) { String key1 = "{key}" + UUID.randomUUID(); String key2 = "{key}" + UUID.randomUUID(); @@ -1137,8 +1182,9 @@ public void randomkey() { } @SneakyThrows - @Test - public void randomKeyBinary() { + @ParameterizedTest + @MethodSource("getClients") + public void randomKeyBinary(GlideClient regularClient) { GlideString key1 = gs("{key}" + UUID.randomUUID()); GlideString key2 = gs("{key}" + UUID.randomUUID()); @@ -1153,9 +1199,10 @@ public void randomKeyBinary() { assertNull(regularClient.randomKeyBinary().get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scan() { + public void scan(GlideClient regularClient) { String initialCursor = "0"; int numberKeys = 500; @@ -1211,9 +1258,10 @@ public void scan() { keys.forEach((key, value) -> assertTrue(ArrayUtils.contains(finalKeysFound, key))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scan_binary() { + public void scan_binary(GlideClient regularClient) { GlideString initialCursor = gs("0"); int numberKeys = 500; @@ -1270,9 +1318,10 @@ public void scan_binary() { keys.forEach((key, value) -> assertTrue(ArrayUtils.contains(finalKeysFound, key))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scan_with_options() { + public void scan_with_options(GlideClient regularClient) { String initialCursor = "0"; String matchPattern = UUID.randomUUID().toString(); @@ -1358,9 +1407,10 @@ public void scan_with_options() { } while (!hashCursor.equals("0")); // 0 is returned for the cursor of the last iteration. } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scan_binary_with_options() { + public void scan_binary_with_options(GlideClient regularClient) { GlideString initialCursor = gs("0"); String matchPattern = UUID.randomUUID().toString(); @@ -1448,8 +1498,9 @@ public void scan_binary_with_options() { } @SneakyThrows - @Test - public void invokeScript_test() { + @ParameterizedTest + @MethodSource("getClients") + public void invokeScript_test(GlideClient regularClient) { String key1 = UUID.randomUUID().toString(); String key2 = UUID.randomUUID().toString(); @@ -1487,8 +1538,9 @@ public void invokeScript_test() { } @SneakyThrows - @Test - public void script_large_keys_and_or_args() { + @ParameterizedTest + @MethodSource("getClients") + public void script_large_keys_and_or_args(GlideClient regularClient) { String str1 = "0".repeat(1 << 12); // 4k String str2 = "0".repeat(1 << 12); // 4k @@ -1530,8 +1582,9 @@ public void script_large_keys_and_or_args() { } @SneakyThrows - @Test - public void invokeScript_gs_test() { + @ParameterizedTest + @MethodSource("getClients") + public void invokeScript_gs_test(GlideClient regularClient) { GlideString key1 = gs(UUID.randomUUID().toString()); GlideString key2 = gs(UUID.randomUUID().toString()); @@ -1573,7 +1626,7 @@ public void invokeScript_gs_test() { } @SneakyThrows - public void scriptExists() { + public void scriptExists(GlideClient regularClient) { Script script1 = new Script("return 'Hello'", true); Script script2 = new Script("return 'World'", true); Boolean[] expected = new Boolean[] {true, false, false}; @@ -1592,9 +1645,10 @@ public void scriptExists() { assertArrayEquals(expected, result); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scriptExistsBinary() { + public void scriptExistsBinary(GlideClient regularClient) { Script script1 = new Script(gs("return 'Hello'"), true); Script script2 = new Script(gs("return 'World'"), true); Boolean[] expected = new Boolean[] {true, false, false}; @@ -1613,9 +1667,10 @@ public void scriptExistsBinary() { assertArrayEquals(expected, result); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scriptFlush() { + public void scriptFlush(GlideClient regularClient) { Script script = new Script("return 'Hello'", true); // Load script @@ -1639,9 +1694,10 @@ public void scriptFlush() { assertArrayEquals(new Boolean[] {false}, result); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void scriptKill() { + public void scriptKill(GlideClient regularClient) { // Verify that script_kill raises an error when no script is running ExecutionException executionException = assertThrows(ExecutionException.class, () -> regularClient.scriptKill().get()); @@ -1697,8 +1753,9 @@ public void scriptKill() { } @SneakyThrows - @Test - public void scriptKill_unkillable() { + @ParameterizedTest + @MethodSource("getClients") + public void scriptKill_unkillable(GlideClient regularClient) { String key = UUID.randomUUID().toString(); String code = createLongRunningLuaScript(5, false); Script script = new Script(code, false); diff --git a/java/integTest/src/test/java/glide/standalone/TransactionTests.java b/java/integTest/src/test/java/glide/standalone/TransactionTests.java index ff910673b1..812b17f6f9 100644 --- a/java/integTest/src/test/java/glide/standalone/TransactionTests.java +++ b/java/integTest/src/test/java/glide/standalone/TransactionTests.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Named.named; import glide.TransactionTestUtilities.TransactionBuilder; import glide.api.GlideClient; @@ -34,6 +35,7 @@ import glide.api.models.commands.function.FunctionRestorePolicy; import glide.api.models.commands.scan.ScanOptions; import glide.api.models.commands.stream.StreamAddOptions; +import glide.api.models.configuration.ProtocolVersion; import glide.api.models.exceptions.RequestException; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -41,43 +43,53 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; import lombok.SneakyThrows; import org.apache.commons.lang3.ArrayUtils; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @Timeout(10) // seconds public class TransactionTests { - private static GlideClient client = null; - - @BeforeAll - @SneakyThrows - public static void init() { - client = GlideClient.createClient(commonClientConfig().requestTimeout(7000).build()).get(); - } - - @AfterAll @SneakyThrows - public static void teardown() { - client.close(); + public static Stream getClients() { + return Stream.of( + Arguments.of( + named( + "RESP2", + GlideClient.createClient( + commonClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP2) + .build()) + .get())), + Arguments.of( + named( + "RESP3", + GlideClient.createClient( + commonClientConfig() + .requestTimeout(7000) + .protocol(ProtocolVersion.RESP3) + .build()) + .get()))); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void custom_command_info() { + public void custom_command_info(GlideClient client) { Transaction transaction = new Transaction().customCommand(new String[] {"info"}); Object[] result = client.exec(transaction).get(); assertTrue(((String) result[0]).contains("# Stats")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void info_test() { + public void info_test(GlideClient client) { Transaction transaction = new Transaction().info().info(new Section[] {CLUSTER}); Object[] result = client.exec(transaction).get(); @@ -86,9 +98,10 @@ public void info_test() { assertFalse(((String) result[1]).contains("# Stats")); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void ping_tests() { + public void ping_tests(GlideClient client) { Transaction transaction = new Transaction(); int numberOfPings = 100; for (int idx = 0; idx < numberOfPings; idx++) { @@ -108,10 +121,19 @@ public void ping_tests() { } } + public static Stream getCommonTransactionBuilders() { + return glide.TransactionTestUtilities.getCommonTransactionBuilders() + .flatMap( + test -> + getClients() + .map(client -> Arguments.of(test.get()[0], test.get()[1], client.get()[0]))); + } + @SneakyThrows @ParameterizedTest(name = "{0}") - @MethodSource("glide.TransactionTestUtilities#getCommonTransactionBuilders") - public void transactions_with_group_of_commands(String testName, TransactionBuilder builder) { + @MethodSource("getCommonTransactionBuilders") + public void transactions_with_group_of_commands( + String testName, TransactionBuilder builder, GlideClient client) { Transaction transaction = new Transaction(); Object[] expectedResult = builder.apply(transaction); @@ -119,11 +141,19 @@ public void transactions_with_group_of_commands(String testName, TransactionBuil assertDeepEquals(expectedResult, results); } + public static Stream getPrimaryNodeTransactionBuilders() { + return glide.TransactionTestUtilities.getPrimaryNodeTransactionBuilders() + .flatMap( + test -> + getClients() + .map(client -> Arguments.of(test.get()[0], test.get()[1], client.get()[0]))); + } + @SneakyThrows @ParameterizedTest(name = "{0}") - @MethodSource("glide.TransactionTestUtilities#getPrimaryNodeTransactionBuilders") + @MethodSource("getPrimaryNodeTransactionBuilders") public void keyless_transactions_with_group_of_commands( - String testName, TransactionBuilder builder) { + String testName, TransactionBuilder builder, GlideClient client) { Transaction transaction = new Transaction(); Object[] expectedResult = builder.apply(transaction); @@ -132,8 +162,9 @@ public void keyless_transactions_with_group_of_commands( } @SneakyThrows - @Test - public void test_transaction_large_values() { + @ParameterizedTest + @MethodSource("getClients") + public void test_transaction_large_values(GlideClient client) { int length = 1 << 25; // 33mb String key = "0".repeat(length); String value = "0".repeat(length); @@ -153,8 +184,9 @@ public void test_transaction_large_values() { } @SneakyThrows - @Test - public void test_standalone_transaction() { + @ParameterizedTest + @MethodSource("getClients") + public void test_standalone_transaction(GlideClient client) { String key = UUID.randomUUID().toString(); String value = UUID.randomUUID().toString(); @@ -180,18 +212,20 @@ public void test_standalone_transaction() { assertArrayEquals(expectedResult, result); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void lastsave() { + public void lastsave(GlideClient client) { var yesterday = Instant.now().minus(1, ChronoUnit.DAYS); var response = client.exec(new Transaction().lastsave()).get(); assertTrue(Instant.ofEpochSecond((long) response[0]).isAfter(yesterday)); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectFreq() { + public void objectFreq(GlideClient client) { String objectFreqKey = "key"; String maxmemoryPolicy = "maxmemory-policy"; @@ -210,9 +244,10 @@ public void objectFreq() { } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectIdletime() { + public void objectIdletime(GlideClient client) { String objectIdletimeKey = "key"; Transaction transaction = new Transaction(); transaction.set(objectIdletimeKey, ""); @@ -222,9 +257,10 @@ public void objectIdletime() { assertTrue((long) response[1] >= 0L); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void objectRefcount() { + public void objectRefcount(GlideClient client) { String objectRefcountKey = "key"; Transaction transaction = new Transaction(); transaction.set(objectRefcountKey, ""); @@ -234,9 +270,10 @@ public void objectRefcount() { assertTrue((long) response[1] >= 0L); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void zrank_zrevrank_withscores() { + public void zrank_zrevrank_withscores(GlideClient client) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.2.0")); String zSetKey1 = "{key}:zsetKey1-" + UUID.randomUUID(); Transaction transaction = new Transaction(); @@ -250,9 +287,10 @@ public void zrank_zrevrank_withscores() { assertArrayEquals(new Object[] {2L, 1.0}, (Object[]) result[2]); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void copy() { + public void copy(GlideClient client) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("6.2.0")); // setup String copyKey1 = "{CopyKey}-1-" + UUID.randomUUID(); @@ -287,9 +325,10 @@ public void copy() { assertArrayEquals(expectedResult, result); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void watch() { + public void watch(GlideClient client) { String key1 = "{key}-1" + UUID.randomUUID(); String key2 = "{key}-2" + UUID.randomUUID(); String key3 = "{key}-3" + UUID.randomUUID(); @@ -342,9 +381,10 @@ public void watch() { assertInstanceOf(RequestException.class, executionException.getCause()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void watch_binary() { + public void watch_binary(GlideClient client) { GlideString key1 = gs("{key}-1" + UUID.randomUUID()); GlideString key2 = gs("{key}-2" + UUID.randomUUID()); GlideString key3 = gs("{key}-3" + UUID.randomUUID()); @@ -403,9 +443,10 @@ public void watch_binary() { assertInstanceOf(RequestException.class, executionException.getCause()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void unwatch() { + public void unwatch(GlideClient client) { String key1 = "{key}-1" + UUID.randomUUID(); String key2 = "{key}-2" + UUID.randomUUID(); String foobarString = "foobar"; @@ -427,42 +468,50 @@ public void unwatch() { assertEquals(foobarString, client.get(key2).get()); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void sort_and_sortReadOnly() { + public void sort_and_sortReadOnly(GlideClient client) { Transaction transaction1 = new Transaction(); Transaction transaction2 = new Transaction(); - String genericKey1 = "{GenericKey}-1-" + UUID.randomUUID(); - String genericKey2 = "{GenericKey}-2-" + UUID.randomUUID(); + var prefix = UUID.randomUUID(); + String genericKey1 = "{GenericKey}-1-" + prefix; + String genericKey2 = "{GenericKey}-2-" + prefix; String[] ascendingListByAge = new String[] {"Bob", "Alice"}; String[] descendingListByAge = new String[] {"Alice", "Bob"}; transaction1 - .hset("user:1", Map.of("name", "Alice", "age", "30")) - .hset("user:2", Map.of("name", "Bob", "age", "25")) + .hset(prefix + "user:1", Map.of("name", "Alice", "age", "30")) + .hset(prefix + "user:2", Map.of("name", "Bob", "age", "25")) .lpush(genericKey1, new String[] {"2", "1"}) .sort( genericKey1, - SortOptions.builder().byPattern("user:*->age").getPattern("user:*->name").build()) + SortOptions.builder() + .byPattern(prefix + "user:*->age") + .getPattern(prefix + "user:*->name") + .build()) .sort( genericKey1, SortOptions.builder() .orderBy(DESC) - .byPattern("user:*->age") - .getPattern("user:*->name") + .byPattern(prefix + "user:*->age") + .getPattern(prefix + "user:*->name") .build()) .sortStore( genericKey1, genericKey2, - SortOptions.builder().byPattern("user:*->age").getPattern("user:*->name").build()) + SortOptions.builder() + .byPattern(prefix + "user:*->age") + .getPattern(prefix + "user:*->name") + .build()) .lrange(genericKey2, 0, -1) .sortStore( genericKey1, genericKey2, SortOptions.builder() .orderBy(DESC) - .byPattern("user:*->age") - .getPattern("user:*->name") + .byPattern(prefix + "user:*->age") + .getPattern(prefix + "user:*->name") .build()) .lrange(genericKey2, 0, -1); @@ -485,13 +534,16 @@ public void sort_and_sortReadOnly() { transaction2 .sortReadOnly( genericKey1, - SortOptions.builder().byPattern("user:*->age").getPattern("user:*->name").build()) + SortOptions.builder() + .byPattern(prefix + "user:*->age") + .getPattern(prefix + "user:*->name") + .build()) .sortReadOnly( genericKey1, SortOptions.builder() .orderBy(DESC) - .byPattern("user:*->age") - .getPattern("user:*->name") + .byPattern(prefix + "user:*->age") + .getPattern(prefix + "user:*->name") .build()); expectedResults = @@ -505,8 +557,9 @@ public void sort_and_sortReadOnly() { } @SneakyThrows - @Test - public void waitTest() { + @ParameterizedTest + @MethodSource("getClients") + public void waitTest(GlideClient client) { // setup String key = UUID.randomUUID().toString(); long numreplicas = 1L; @@ -527,8 +580,9 @@ public void waitTest() { } @SneakyThrows - @Test - public void scan_test() { + @ParameterizedTest + @MethodSource("getClients") + public void scan_test(GlideClient client) { // setup String key = UUID.randomUUID().toString(); Map msetMap = Map.of(key, UUID.randomUUID().toString()); @@ -548,8 +602,9 @@ public void scan_test() { } @SneakyThrows - @Test - public void scan_binary_test() { + @ParameterizedTest + @MethodSource("getClients") + public void scan_binary_test(GlideClient client) { // setup String key = UUID.randomUUID().toString(); Map msetMap = Map.of(key, UUID.randomUUID().toString()); @@ -568,8 +623,9 @@ public void scan_binary_test() { } @SneakyThrows - @Test - public void scan_with_options_test() { + @ParameterizedTest + @MethodSource("getClients") + public void scan_with_options_test(GlideClient client) { // setup Transaction setupTransaction = new Transaction(); @@ -627,8 +683,9 @@ public void scan_with_options_test() { } @SneakyThrows - @Test - public void scan_binary_with_options_test() { + @ParameterizedTest + @MethodSource("getClients") + public void scan_binary_with_options_test(GlideClient client) { // setup Transaction setupTransaction = new Transaction().withBinaryOutput(); @@ -686,9 +743,10 @@ HASH, gs("{hash}-" + UUID.randomUUID()), } } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_transaction_dump_restore() { + public void test_transaction_dump_restore(GlideClient client) { GlideString key1 = gs("{key}-1" + UUID.randomUUID()); GlideString key2 = gs("{key}-2" + UUID.randomUUID()); String value = UUID.randomUUID().toString(); @@ -710,9 +768,10 @@ public void test_transaction_dump_restore() { assertEquals(value, response[1]); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_transaction_function_dump_restore() { + public void test_transaction_function_dump_restore(GlideClient client) { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0")); String libName = "mylib"; String funcName = "myfun"; @@ -733,9 +792,10 @@ public void test_transaction_function_dump_restore() { assertEquals(OK, response[0]); } - @Test + @ParameterizedTest + @MethodSource("getClients") @SneakyThrows - public void test_transaction_xinfoStream() { + public void test_transaction_xinfoStream(GlideClient client) { Transaction transaction = new Transaction(); final String streamKey = "{streamKey}-" + UUID.randomUUID(); LinkedHashMap expectedStreamInfo = @@ -788,8 +848,9 @@ public void test_transaction_xinfoStream() { } @SneakyThrows - @Test - public void binary_strings() { + @ParameterizedTest + @MethodSource("getClients") + public void binary_strings(GlideClient client) { String key = UUID.randomUUID().toString(); client.set(key, "_").get(); // use dump to ensure that we have non-string convertible bytes diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index 2bfb9a3bbd..94fb580803 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -545,12 +545,12 @@ export interface BaseClientConfiguration { */ requestTimeout?: number; /** - * Represents the client's read from strategy. + * The client's read from strategy. * If not set, `Primary` will be used. */ readFrom?: ReadFrom; /** - * Choose the serialization protocol to be used with the server. + * Serialization protocol to be used. * If not set, `RESP3` will be used. */ protocol?: ProtocolVersion; diff --git a/python/python/glide/config.py b/python/python/glide/config.py index 87f6b06087..2388a8a134 100644 --- a/python/python/glide/config.py +++ b/python/python/glide/config.py @@ -158,6 +158,7 @@ def __init__( This duration encompasses sending the request, awaiting for a response from the server, and any required reconnections or retries. If the specified timeout is exceeded for a pending request, it will result in a timeout error. If not set, a default value will be used. client_name (Optional[str]): Client name to be used for the client. Will be used with CLIENT SETNAME command during connection establishment. + protocol (ProtocolVersion): Serialization protocol to be used. If not set, `RESP3` will be used. """ self.addresses = addresses self.use_tls = use_tls