package com.lambdaworks.redis; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; import java.lang.reflect.Proxy; import java.util.concurrent.TimeUnit; import org.junit.Test; import com.google.common.base.Stopwatch; import com.lambdaworks.redis.api.async.RedisAsyncCommands; import com.lambdaworks.redis.api.sync.RedisCommands; public class PoolConnectionTest extends AbstractRedisClientTest { @Test public void twoConnections() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisCommands<String, String> c1 = pool.allocateConnection(); RedisConnection<String, String> c2 = pool.allocateConnection(); String result1 = c1.ping(); String result2 = c2.ping(); assertThat(result1).isEqualTo("PONG"); assertThat(result2).isEqualTo("PONG"); c1.close(); c2.close(); pool.close(); } @Test(expected = UnsupportedOperationException.class) public void getStatefulConnection() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisCommands<String, String> c1 = pool.allocateConnection(); try { c1.getStatefulConnection(); } finally { c1.close(); pool.close(); } } @Test public void sameConnectionAfterFree() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisCommands<String, String> c1 = pool.allocateConnection(); pool.freeConnection(c1); assertConnectionStillThere(c1); RedisConnection<String, String> c2 = pool.allocateConnection(); assertThat(c2).isSameAs(c1); c2.close(); pool.close(); } @Test public void connectionCloseDoesNotClose() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisConnection<String, String> c1 = pool.allocateConnection(); c1.close(); RedisConnection<String, String> actualConnection1 = assertConnectionStillThere(c1); RedisConnection<String, String> c2 = pool.allocateConnection(); assertThat(c2).isSameAs(c1); RedisConnection<String, String> actualConnection2 = assertConnectionStillThere(c2); assertThat(actualConnection1).isSameAs(actualConnection2); c2.close(); pool.close(); } @SuppressWarnings("unchecked") private RedisConnection<String, String> assertConnectionStillThere(RedisConnection<String, String> c1) { // unwrap code from RedisConnectionPool destroyObject if (Proxy.isProxyClass(c1.getClass())) { RedisConnectionPool.PooledConnectionInvocationHandler<RedisConnection<String, String>> invocationHandler; invocationHandler = (RedisConnectionPool.PooledConnectionInvocationHandler<RedisConnection<String, String>>) Proxy .getInvocationHandler(c1); RedisConnection<String, String> connection = invocationHandler.getConnection(); assertThat(connection).isNotNull(); return connection; } return null; } @Test public void releaseConnectionWithClose() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisConnection<String, String> c1 = pool.allocateConnection(); assertThat(pool.getNumActive()).isEqualTo(1); c1.close(); assertThat(pool.getNumActive()).isEqualTo(0); pool.allocateConnection(); assertThat(pool.getNumActive()).isEqualTo(1); } @Test public void connectionsClosedAfterPoolClose() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisCommands<String, String> c1 = pool.allocateConnection(); pool.freeConnection(c1); pool.close(); try { c1.ping(); fail("Missing Exception: Connection closed"); } catch (Exception e) { } } @Test public void connectionNotClosedWhenBorrowed() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisConnection<String, String> c1 = pool.allocateConnection(); pool.close(); c1.ping(); c1.close(); } @Test public void connectionNotClosedWhenBorrowed2() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisCommands<String, String> c1 = pool.allocateConnection(); pool.freeConnection(c1); c1 = pool.allocateConnection(); pool.close(); c1.ping(); c1.close(); } @Test public void testResourceCleaning() throws Exception { RedisClient redisClient = newRedisClient(); assertThat(redisClient.getChannelCount()).isEqualTo(0); assertThat(redisClient.getResourceCount()).isEqualTo(0); RedisConnectionPool<RedisAsyncCommands<String, String>> pool1 = redisClient.asyncPool(); assertThat(redisClient.getChannelCount()).isEqualTo(0); assertThat(redisClient.getResourceCount()).isEqualTo(1); pool1.allocateConnection(); assertThat(redisClient.getChannelCount()).isEqualTo(1); assertThat(redisClient.getResourceCount()).isEqualTo(2); RedisConnectionPool<RedisCommands<String, String>> pool2 = redisClient.pool(); assertThat(redisClient.getResourceCount()).isEqualTo(3); pool2.allocateConnection(); assertThat(redisClient.getResourceCount()).isEqualTo(4); redisClient.pool().close(); assertThat(redisClient.getResourceCount()).isEqualTo(4); FastShutdown.shutdown(redisClient); assertThat(redisClient.getChannelCount()).isEqualTo(0); assertThat(redisClient.getResourceCount()).isEqualTo(0); } @Test public void syncPoolPerformanceTest() throws Exception { RedisConnectionPool<RedisCommands<String, String>> pool = client.pool(); RedisConnection<String, String> c1 = pool.allocateConnection(); c1.ping(); Stopwatch stopwatch = Stopwatch.createStarted(); for (int i = 0; i < 1000; i++) { c1.ping(); } long elapsed = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS); log.info("syncPoolPerformanceTest Duration: " + elapsed + "ms"); c1.close(); pool.close(); } @Test public void asyncPoolPerformanceTest() throws Exception { RedisConnectionPool<RedisAsyncCommands<String, String>> pool = client.asyncPool(); RedisAsyncConnection<String, String> c1 = pool.allocateConnection(); c1.ping(); Stopwatch stopwatch = Stopwatch.createStarted(); for (int i = 0; i < 1000; i++) { c1.ping(); } long elapsed = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS); log.info("asyncPoolPerformanceTest Duration: " + elapsed + "ms"); c1.close(); pool.close(); } }