JedisPooledTest.java
package redis.clients.jedis;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anything;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;
public class JedisPooledTest {
private static final EndpointConfig endpointStandalone7 = HostAndPorts.getRedisEndpoint(
"standalone7-with-lfu-policy");
private static final EndpointConfig endpointStandalone1 = HostAndPorts.getRedisEndpoint(
"standalone1"); // password protected
@Test
public void checkCloseableConnections() {
JedisPooled pool = new JedisPooled(new ConnectionPoolConfig(), endpointStandalone7.getHost(),
endpointStandalone7.getPort(), 2000);
pool.set("foo", "bar");
assertEquals("bar", pool.get("foo"));
pool.close();
assertTrue(pool.getPool().isClosed());
}
@Test
public void checkResourceWithConfig() {
try (JedisPooled pool = new JedisPooled(endpointStandalone7.getHostAndPort(),
DefaultJedisClientConfig.builder().socketTimeoutMillis(5000).build())) {
try (Connection jedis = pool.getPool().getResource()) {
assertTrue(jedis.ping());
assertEquals(5000, jedis.getSoTimeout());
}
}
}
@Test
public void checkPoolOverflow() {
GenericObjectPoolConfig<Connection> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(1);
config.setBlockWhenExhausted(false);
try (JedisPooled pool = new JedisPooled(endpointStandalone7.getHostAndPort(), config);
Connection jedis = pool.getPool().getResource()) {
assertThrows(JedisException.class, () -> pool.getPool().getResource());
}
}
@Test
public void startWithUrlString() {
try (Jedis j = new Jedis(endpointStandalone1.getHostAndPort())) {
j.auth(endpointStandalone1.getPassword());
j.select(2);
j.set("foo", "bar");
}
try (JedisPooled pool = new JedisPooled(
endpointStandalone1.getURIBuilder().credentials("", endpointStandalone1.getPassword()).path("/2").build()
.toString())) {
assertEquals("bar", pool.get("foo"));
}
}
@Test
public void startWithUrl() throws URISyntaxException {
try (Jedis j = new Jedis(endpointStandalone1.getHostAndPort())) {
j.auth(endpointStandalone1.getPassword());
j.select(2);
j.set("foo", "bar");
}
try (JedisPooled pool = new JedisPooled(
endpointStandalone1.getURIBuilder().credentials("", endpointStandalone1.getPassword()).path("/2").build())) {
assertEquals("bar", pool.get("foo"));
}
}
@Test
public void shouldThrowExceptionForInvalidURI() {
assertThrows(Exception.class, ()->new JedisPooled(new URI("localhost:6380")));
}
@Test
public void allowUrlWithNoDBAndNoPassword() throws URISyntaxException {
new JedisPooled(endpointStandalone1.getURI().toString()).close();
new JedisPooled(endpointStandalone1.getURI()).close();
}
@Test
public void customClientName() {
try (JedisPooled pool = new JedisPooled(endpointStandalone7.getHostAndPort(), DefaultJedisClientConfig.builder()
.clientName("my_shiny_client_name").build());
Connection jedis = pool.getPool().getResource()) {
assertEquals("my_shiny_client_name", new Jedis(jedis).clientGetname());
}
}
@Test
public void invalidClientName() {
try (JedisPooled pool = new JedisPooled(endpointStandalone7.getHostAndPort(), DefaultJedisClientConfig.builder()
.clientName("invalid client name").build());
Connection jedis = pool.getPool().getResource()) {
} catch (Exception e) {
if (!e.getMessage().startsWith("client info cannot contain space")) {
fail("invalid client name test fail");
}
}
}
@Test
public void getNumActiveWhenPoolIsClosed() {
JedisPooled pool = new JedisPooled(endpointStandalone7.getHostAndPort());
try (Connection j = pool.getPool().getResource()) {
j.ping();
}
pool.close();
assertEquals(0, pool.getPool().getNumActive());
}
@Test
public void getNumActiveReturnsTheCorrectNumber() {
try (JedisPooled pool = new JedisPooled(new ConnectionPoolConfig(),
endpointStandalone7.getHost(), endpointStandalone7.getPort(), 2000)) {
Connection jedis = pool.getPool().getResource();
assertEquals(1, pool.getPool().getNumActive());
Connection jedis2 = pool.getPool().getResource();
assertEquals(2, pool.getPool().getNumActive());
jedis.close();
assertEquals(1, pool.getPool().getNumActive());
jedis2.close();
assertEquals(0, pool.getPool().getNumActive());
}
}
@Test
public void closeResourceTwice() {
try (JedisPooled pool = new JedisPooled(new ConnectionPoolConfig(),
endpointStandalone7.getHost(), endpointStandalone7.getPort(), 2000)) {
Connection j = pool.getPool().getResource();
j.ping();
j.close();
j.close();
}
}
@Test
public void closeBrokenResourceTwice() {
try (JedisPooled pool = new JedisPooled(new ConnectionPoolConfig(),
endpointStandalone7.getHost(), endpointStandalone7.getPort(), 2000)) {
Connection j = pool.getPool().getResource();
try {
// make connection broken
j.getOne();
fail();
} catch (Exception e) {
assertInstanceOf(JedisConnectionException.class, e);
}
assertTrue(j.isBroken());
j.close();
j.close();
}
}
@Test
public void testResetValidCredentials() {
DefaultRedisCredentialsProvider credentialsProvider =
new DefaultRedisCredentialsProvider(new DefaultRedisCredentials(null, "bad password"));
try (JedisPooled pool = new JedisPooled(endpointStandalone1.getHostAndPort(), DefaultJedisClientConfig.builder()
.credentialsProvider(credentialsProvider).build())) {
try {
pool.get("foo");
fail("Should not get resource from pool");
} catch (JedisException e) { }
assertEquals(0, pool.getPool().getNumActive());
credentialsProvider.setCredentials(new DefaultRedisCredentials(null, endpointStandalone1.getPassword()));
assertThat(pool.get("foo"), anything());
}
}
@Test
public void testCredentialsProvider() {
final AtomicInteger prepareCount = new AtomicInteger();
final AtomicInteger cleanupCount = new AtomicInteger();
final AtomicBoolean validPassword = new AtomicBoolean(false);
RedisCredentialsProvider credentialsProvider = new RedisCredentialsProvider() {
@Override
public void prepare() {
prepareCount.incrementAndGet();
}
@Override
public RedisCredentials get() {
if (!validPassword.get()) {
return new RedisCredentials() {
@Override
public char[] getPassword() {
return "invalidPass".toCharArray();
}
};
}
return new RedisCredentials() {
@Override
public String getUser() {
return null;
}
@Override
public char[] getPassword() {
return endpointStandalone1.getPassword().toCharArray();
}
};
}
@Override
public void cleanUp() {
cleanupCount.incrementAndGet();
}
};
// TODO: do it without the help of pool config; from Connection constructor? (configurable) force ping?
GenericObjectPoolConfig<Connection> poolConfig = new GenericObjectPoolConfig<>();
poolConfig.setMaxTotal(1);
poolConfig.setTestOnBorrow(true);
try (JedisPooled pool = new JedisPooled(endpointStandalone1.getHostAndPort(), DefaultJedisClientConfig.builder()
.credentialsProvider(credentialsProvider).build(), poolConfig)) {
try {
pool.get("foo");
fail("Should not get resource from pool");
} catch (JedisException e) {
//ignore
}
assertEquals(0, pool.getPool().getNumActive() + pool.getPool().getNumIdle() + pool.getPool().getNumWaiters());
assertThat(prepareCount.getAndSet(0), greaterThanOrEqualTo(1));
assertThat(cleanupCount.getAndSet(0), greaterThanOrEqualTo(1));
validPassword.set(true);
assertThat(pool.get("foo"), anything());
assertThat(prepareCount.get(), equalTo(1));
assertThat(cleanupCount.get(), equalTo(1));
}
}
}