forked from valkey-io/valkey-glide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5f687a3
commit 3412cf0
Showing
4 changed files
with
533 additions
and
57 deletions.
There are no files selected for viewing
29 changes: 0 additions & 29 deletions
29
java/integTest/src/test/java/glide/cluster/ClientTest.java
This file was deleted.
Oops, something went wrong.
272 changes: 272 additions & 0 deletions
272
java/integTest/src/test/java/glide/cluster/ClientTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,272 @@ | ||
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */ | ||
package glide.cluster; | ||
|
||
import static glide.TestConfiguration.CLUSTER_PORTS; | ||
import static glide.api.BaseClient.OK; | ||
import static glide.api.models.commands.InfoOptions.Section.SERVER; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
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 glide.api.RedisClusterClient; | ||
import glide.api.models.ClusterValue; | ||
import glide.api.models.commands.InfoOptions; | ||
import glide.api.models.configuration.NodeAddress; | ||
import glide.api.models.configuration.RedisClusterClientConfiguration; | ||
import glide.api.models.configuration.RedisCredentials; | ||
import glide.api.models.exceptions.ClosingException; | ||
import glide.api.models.exceptions.RequestException; | ||
import java.lang.module.ModuleDescriptor; | ||
import java.security.SecureRandom; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import java.util.stream.Collectors; | ||
import lombok.SneakyThrows; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
|
||
public class ClientTests { | ||
private RedisClusterClientConfiguration.RedisClusterClientConfigurationBuilder<?, ?> | ||
commonClusterClientConfig() { | ||
return RedisClusterClientConfiguration.builder() | ||
.address(NodeAddress.builder().port(CLUSTER_PORTS[0]).build()); | ||
} | ||
|
||
private static Map<String, String> parseInfoResponse(ClusterValue<String> infoResponse) { | ||
String value; | ||
if (infoResponse.hasSingleData()) { | ||
value = infoResponse.getSingleValue(); | ||
} else { | ||
value = infoResponse.getMultiValue().entrySet().iterator().next().getValue(); | ||
} | ||
|
||
return value | ||
.lines() | ||
.filter(line -> line.contains(":")) | ||
.map(line -> line.split(":", 2)) | ||
.collect( | ||
Collectors.toMap( | ||
parts -> parts[0], | ||
parts -> parts[1], | ||
(existingValue, newValue) -> newValue, | ||
HashMap::new)); | ||
} | ||
|
||
private static String getRandomString(int length) { | ||
String asciiLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
SecureRandom random = new SecureRandom(); | ||
StringBuilder sb = new StringBuilder(length); | ||
|
||
for (int i = 0; i < length; i++) { | ||
int index = random.nextInt(asciiLetters.length()); | ||
char randomChar = asciiLetters.charAt(index); | ||
sb.append(randomChar); | ||
} | ||
|
||
return sb.toString(); | ||
} | ||
|
||
@SneakyThrows | ||
private Boolean check_if_server_version_gte(RedisClusterClient client, String minVersion) { | ||
ClusterValue<String> infoStr = client.info(InfoOptions.builder().section(SERVER).build()).get(); | ||
String redisVersion = parseInfoResponse(infoStr).get("redis_version"); | ||
assertNotNull(redisVersion); | ||
return ModuleDescriptor.Version.parse(redisVersion) | ||
.compareTo(ModuleDescriptor.Version.parse(minVersion)) | ||
>= 0; | ||
} | ||
|
||
@SneakyThrows | ||
@Test | ||
public void register_client_name_and_version() { | ||
RedisClusterClient client = | ||
RedisClusterClient.CreateClient(commonClusterClientConfig().build()).get(); | ||
|
||
String minVersion = "7.2.0"; | ||
assumeTrue( | ||
check_if_server_version_gte(client, minVersion), "Redis version required >= " + minVersion); | ||
String info = | ||
(String) client.customCommand(new String[] {"CLIENT", "INFO"}).get().getSingleValue(); | ||
assertTrue(info.contains("lib-name=GlideJava")); | ||
assertTrue(info.contains("lib-ver=unknown")); | ||
|
||
client.close(); | ||
} | ||
|
||
@SneakyThrows | ||
@Test | ||
public void send_and_receive_large_values() { | ||
RedisClusterClient client = | ||
RedisClusterClient.CreateClient(commonClusterClientConfig().build()).get(); | ||
|
||
int length = 2 ^ 16; | ||
String key = getRandomString(length); | ||
String value = getRandomString(length); | ||
|
||
assertEquals(length, key.length()); | ||
assertEquals(length, value.length()); | ||
assertEquals(OK, client.set(key, value).get()); | ||
assertEquals(value, client.get(key).get()); | ||
|
||
client.close(); | ||
} | ||
|
||
@SneakyThrows | ||
@Test | ||
public void send_and_receive_non_ascii_unicode() { | ||
RedisClusterClient client = | ||
RedisClusterClient.CreateClient(commonClusterClientConfig().build()).get(); | ||
|
||
String key = "foo"; | ||
String value = "שלום hello 汉字"; | ||
|
||
assertEquals(OK, client.set(key, value).get()); | ||
assertEquals(value, client.get(key).get()); | ||
|
||
client.close(); | ||
} | ||
|
||
@SneakyThrows | ||
@ParameterizedTest | ||
@ValueSource(ints = {100, 2 ^ 16}) | ||
public void client_can_handle_concurrent_workload(int valueSize) { | ||
ExecutorService executorService = Executors.newFixedThreadPool(8); | ||
RedisClusterClient client = | ||
RedisClusterClient.CreateClient(commonClusterClientConfig().build()).get(); | ||
CompletableFuture[] futures = new CompletableFuture[100]; | ||
|
||
for (int i = 0; i < 100; i++) { | ||
futures[i] = | ||
CompletableFuture.runAsync( | ||
() -> { | ||
String key = getRandomString(valueSize); | ||
String value = getRandomString(valueSize); | ||
try { | ||
assertEquals(OK, client.set(key, value).get()); | ||
assertEquals(value, client.get(key).get()); | ||
} catch (InterruptedException | ExecutionException e) { | ||
throw new RuntimeException(e); | ||
} | ||
}, | ||
executorService); | ||
} | ||
|
||
CompletableFuture.allOf(futures).join(); | ||
|
||
client.close(); | ||
executorService.shutdown(); | ||
} | ||
|
||
@SneakyThrows | ||
@Test | ||
public void can_connect_with_auth_requirepass() { | ||
RedisClusterClient client = | ||
RedisClusterClient.CreateClient(commonClusterClientConfig().build()).get(); | ||
|
||
String password = "TEST_AUTH"; | ||
client.customCommand(new String[] {"CONFIG", "SET", "requirepass", password}).get(); | ||
|
||
// Creation of a new client without a password should fail | ||
ExecutionException exception = | ||
assertThrows( | ||
ExecutionException.class, | ||
() -> RedisClusterClient.CreateClient(commonClusterClientConfig().build()).get()); | ||
assertTrue(exception.getCause() instanceof ClosingException); | ||
|
||
// Creation of a new client with credentials | ||
RedisClusterClient auth_client = | ||
RedisClusterClient.CreateClient( | ||
commonClusterClientConfig() | ||
.credentials(RedisCredentials.builder().password(password).build()) | ||
.build()) | ||
.get(); | ||
|
||
String key = getRandomString(10); | ||
String value = getRandomString(10); | ||
|
||
assertEquals(OK, auth_client.set(key, value).get()); | ||
assertEquals(value, auth_client.get(key).get()); | ||
|
||
// Reset password | ||
client.customCommand(new String[] {"CONFIG", "SET", "requirepass", ""}).get(); | ||
|
||
auth_client.close(); | ||
client.close(); | ||
} | ||
|
||
@SneakyThrows | ||
@Test | ||
public void can_connect_with_auth_acl() { | ||
RedisClusterClient client = | ||
RedisClusterClient.CreateClient(commonClusterClientConfig().build()).get(); | ||
|
||
String username = "testuser"; | ||
String password = "TEST_AUTH"; | ||
assertEquals( | ||
OK, | ||
client | ||
.customCommand( | ||
new String[] { | ||
"ACL", | ||
"SETUSER", | ||
username, | ||
"on", | ||
"allkeys", | ||
"+get", | ||
"+cluster", | ||
"+ping", | ||
"+info", | ||
"+client", | ||
">" + password, | ||
}) | ||
.get() | ||
.getSingleValue()); | ||
|
||
String key = getRandomString(10); | ||
String value = getRandomString(10); | ||
|
||
assertEquals(OK, client.set(key, value).get()); | ||
|
||
// Creation of a new cluster client with credentials | ||
RedisClusterClient testUserClient = | ||
RedisClusterClient.CreateClient( | ||
commonClusterClientConfig() | ||
.credentials( | ||
RedisCredentials.builder().username(username).password(password).build()) | ||
.build()) | ||
.get(); | ||
|
||
assertEquals(value, testUserClient.get(key).get()); | ||
|
||
ExecutionException executionException = | ||
assertThrows(ExecutionException.class, () -> testUserClient.set("foo", "bar").get()); | ||
assertTrue(executionException.getCause() instanceof RequestException); | ||
|
||
client.customCommand(new String[] {"ACL", "DELUSER", username}).get(); | ||
|
||
testUserClient.close(); | ||
client.close(); | ||
} | ||
|
||
@SneakyThrows | ||
@Test | ||
public void custom_command_info() { | ||
RedisClusterClient client = | ||
RedisClusterClient.CreateClient( | ||
commonClusterClientConfig().clientName("TEST_CLIENT_NAME").build()) | ||
.get(); | ||
|
||
String clientInfo = | ||
(String) client.customCommand(new String[] {"CLIENT", "INFO"}).get().getSingleValue(); | ||
assertTrue(clientInfo.contains("name=TEST_CLIENT_NAME")); | ||
|
||
client.close(); | ||
} | ||
} |
28 changes: 0 additions & 28 deletions
28
java/integTest/src/test/java/glide/standalone/ClientTest.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.