package org.jooby.jedis;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.junit.Assert.assertEquals;
import java.net.URI;
import javax.inject.Provider;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.jooby.Env;
import org.jooby.test.MockUnit;
import org.jooby.test.MockUnit.Block;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.name.Names;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigValueFactory;
import javaslang.control.Try.CheckedRunnable;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Redis.class, JedisPool.class, GenericObjectPoolConfig.class })
public class RedisTest {
private Block onManaged = unit -> {
Env env = unit.get(Env.class);
expect(env.onStart(isA(CheckedRunnable.class))).andReturn(env);
expect(env.onStop(isA(CheckedRunnable.class))).andReturn(env);
};
@SuppressWarnings("unchecked")
@Test
public void defaults() throws Exception {
Config config = jedisConfig()
.withValue("db", ConfigValueFactory.fromAnyRef("redis://localhost:6780"));
new MockUnit(Env.class, Binder.class)
.expect(unit -> {
Env env = unit.get(Env.class);
expect(env.serviceKey()).andReturn(new Env.ServiceKey());
})
.expect(unit -> {
GenericObjectPoolConfig poolConfig = unit
.mockConstructor(GenericObjectPoolConfig.class);
poolConfig.setBlockWhenExhausted(true);
poolConfig
.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
poolConfig.setJmxEnabled(false);
poolConfig.setJmxNamePrefix("redis-pool");
poolConfig.setLifo(true);
poolConfig.setMaxIdle(10);
poolConfig.setMaxTotal(128);
poolConfig.setMaxWaitMillis(-1);
poolConfig.setMinEvictableIdleTimeMillis(1800000L);
poolConfig.setMinIdle(10);
poolConfig.setNumTestsPerEvictionRun(3);
poolConfig.setSoftMinEvictableIdleTimeMillis(1800000L);
poolConfig.setTestOnBorrow(false);
poolConfig.setTestOnReturn(false);
poolConfig.setTestWhileIdle(false);
poolConfig.setTimeBetweenEvictionRunsMillis(-1);
JedisPool pool = unit.mockConstructor(
JedisPool.class,
new Class[]{GenericObjectPoolConfig.class, URI.class, int.class },
poolConfig, URI.create("redis://localhost:6780"), 2000);
AnnotatedBindingBuilder<JedisPool> jpABB = unit.mock(AnnotatedBindingBuilder.class);
jpABB.toInstance(pool);
jpABB.toInstance(pool);
AnnotatedBindingBuilder<Jedis> jABB = unit.mock(AnnotatedBindingBuilder.class);
expect(jABB.toProvider(isA(Provider.class))).andReturn(jABB);
expect(jABB.toProvider(isA(Provider.class))).andReturn(jABB);
Binder binder = unit.get(Binder.class);
expect(binder.bind(Key.get(JedisPool.class))).andReturn(jpABB);
expect(binder.bind(Key.get(Jedis.class))).andReturn(jABB);
expect(binder.bind(Key.get(JedisPool.class, Names.named("db")))).andReturn(jpABB);
expect(binder.bind(Key.get(Jedis.class, Names.named("db")))).andReturn(jABB);
})
.expect(onManaged)
.run(unit -> {
new Redis().configure(unit.get(Env.class), config, unit.get(Binder.class));
});
}
@SuppressWarnings("unchecked")
@Test
public void shouldGetJedisInstance() throws Exception {
Config config = jedisConfig()
.withValue("db", ConfigValueFactory.fromAnyRef("redis://localhost:6780"));
new MockUnit(Env.class, Binder.class, Jedis.class)
.expect(unit -> {
Env env = unit.get(Env.class);
expect(env.serviceKey()).andReturn(new Env.ServiceKey());
})
.expect(unit -> {
GenericObjectPoolConfig poolConfig = unit
.mockConstructor(GenericObjectPoolConfig.class);
poolConfig.setBlockWhenExhausted(true);
poolConfig
.setEvictionPolicyClassName(
"org.apache.commons.pool2.impl.DefaultEvictionPolicy");
poolConfig.setJmxEnabled(false);
poolConfig.setJmxNamePrefix("redis-pool");
poolConfig.setLifo(true);
poolConfig.setMaxIdle(10);
poolConfig.setMaxTotal(128);
poolConfig.setMaxWaitMillis(-1);
poolConfig.setMinEvictableIdleTimeMillis(1800000L);
poolConfig.setMinIdle(10);
poolConfig.setNumTestsPerEvictionRun(3);
poolConfig.setSoftMinEvictableIdleTimeMillis(1800000L);
poolConfig.setTestOnBorrow(false);
poolConfig.setTestOnReturn(false);
poolConfig.setTestWhileIdle(false);
poolConfig.setTimeBetweenEvictionRunsMillis(-1);
JedisPool pool = unit.mockConstructor(
JedisPool.class,
new Class[]{GenericObjectPoolConfig.class, URI.class, int.class },
poolConfig, URI.create("redis://localhost:6780"), 2000);
expect(pool.getResource()).andReturn(unit.get(Jedis.class));
AnnotatedBindingBuilder<JedisPool> jpABB = unit.mock(AnnotatedBindingBuilder.class);
jpABB.toInstance(pool);
jpABB.toInstance(pool);
AnnotatedBindingBuilder<Jedis> jABB = unit.mock(AnnotatedBindingBuilder.class);
expect(jABB.toProvider(isA(Provider.class))).andReturn(jABB);
expect(jABB.toProvider(unit.capture(Provider.class))).andReturn(jABB);
Binder binder = unit.get(Binder.class);
expect(binder.bind(Key.get(JedisPool.class))).andReturn(jpABB);
expect(binder.bind(Key.get(Jedis.class))).andReturn(jABB);
expect(binder.bind(Key.get(JedisPool.class, Names.named("db")))).andReturn(jpABB);
expect(binder.bind(Key.get(Jedis.class, Names.named("db")))).andReturn(jABB);
})
.expect(onManaged)
.run(unit -> {
new Redis().configure(unit.get(Env.class), config, unit.get(Binder.class));
}, unit -> {
assertEquals(unit.get(Jedis.class), unit.captured(Provider.class).iterator().next()
.get());
});
}
@SuppressWarnings("unchecked")
@Test
public void jedisConfigOverride() throws Exception {
Config config = jedisConfig()
.withValue("db", ConfigValueFactory.fromAnyRef("redis://localhost:6780"))
.withValue("jedis.db.maxTotal", ConfigValueFactory.fromAnyRef(8));
new MockUnit(Env.class, Binder.class)
.expect(unit -> {
Env env = unit.get(Env.class);
expect(env.serviceKey()).andReturn(new Env.ServiceKey());
})
.expect(unit -> {
GenericObjectPoolConfig poolConfig = unit
.mockConstructor(GenericObjectPoolConfig.class);
poolConfig.setBlockWhenExhausted(true);
poolConfig
.setEvictionPolicyClassName(
"org.apache.commons.pool2.impl.DefaultEvictionPolicy");
poolConfig.setJmxEnabled(false);
poolConfig.setJmxNamePrefix("redis-pool");
poolConfig.setLifo(true);
poolConfig.setMaxIdle(10);
poolConfig.setMaxTotal(8);
poolConfig.setMaxWaitMillis(-1);
poolConfig.setMinEvictableIdleTimeMillis(1800000L);
poolConfig.setMinIdle(10);
poolConfig.setNumTestsPerEvictionRun(3);
poolConfig.setSoftMinEvictableIdleTimeMillis(1800000L);
poolConfig.setTestOnBorrow(false);
poolConfig.setTestOnReturn(false);
poolConfig.setTestWhileIdle(false);
poolConfig.setTimeBetweenEvictionRunsMillis(-1);
JedisPool pool = unit.mockConstructor(
JedisPool.class,
new Class[]{GenericObjectPoolConfig.class, URI.class, int.class },
poolConfig, URI.create("redis://localhost:6780"), 2000);
AnnotatedBindingBuilder<JedisPool> jpABB = unit.mock(AnnotatedBindingBuilder.class);
jpABB.toInstance(pool);
jpABB.toInstance(pool);
AnnotatedBindingBuilder<Jedis> jABB = unit.mock(AnnotatedBindingBuilder.class);
expect(jABB.toProvider(isA(Provider.class))).andReturn(jABB);
expect(jABB.toProvider(isA(Provider.class))).andReturn(jABB);
Binder binder = unit.get(Binder.class);
expect(binder.bind(Key.get(JedisPool.class))).andReturn(jpABB);
expect(binder.bind(Key.get(Jedis.class))).andReturn(jABB);
expect(binder.bind(Key.get(JedisPool.class, Names.named("db")))).andReturn(jpABB);
expect(binder.bind(Key.get(Jedis.class, Names.named("db")))).andReturn(jABB);
})
.expect(onManaged)
.run(unit -> {
new Redis().configure(unit.get(Env.class), config, unit.get(Binder.class));
});
}
@Test
public void defaultConfig() throws Exception {
assertEquals(jedisConfig(), new Redis().config());
}
private Config jedisConfig() {
return ConfigFactory.parseResources(getClass(), "jedis.conf");
}
}