content: package redis.clients.jedis.tests;
  
  import java.net.URI;
  import java.net.URISyntaxException;
  import java.util.concurrent.atomic.AtomicInteger;
  
  import org.apache.commons.pool2.PooledObject;
  import org.apache.commons.pool2.PooledObjectFactory;
  import org.apache.commons.pool2.impl.DefaultPooledObject;
  import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
  import org.junit.Assert;
  import org.junit.Test;
  
  import redis.clients.jedis.HostAndPort;
  import redis.clients.jedis.Jedis;
  import redis.clients.jedis.JedisPool;
  import redis.clients.jedis.JedisPoolConfig;
  import redis.clients.jedis.Transaction;
  import redis.clients.jedis.exceptions.InvalidURIException;
  import redis.clients.jedis.exceptions.JedisConnectionException;
  import redis.clients.jedis.exceptions.JedisException;
  
  public class JedisPoolTest extends Assert {
    private static HostAndPort hnp = HostAndPortUtil.getRedisServers().get(0);
  
    @Test
    public void checkConnections() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000);
      Jedis jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.set("foo", "bar");
      assertEquals("bar", jedis.get("foo"));
      jedis.close();
      pool.destroy();
      assertTrue(pool.isClosed());
    }
  
    @Test
    public void checkCloseableConnections() throws Exception {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000);
      Jedis jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.set("foo", "bar");
      assertEquals("bar", jedis.get("foo"));
      jedis.close();
      pool.close();
      assertTrue(pool.isClosed());
    }
  
    @Test
    public void checkConnectionWithDefaultPort() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort());
      Jedis jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.set("foo", "bar");
      assertEquals("bar", jedis.get("foo"));
      jedis.close();
      pool.destroy();
      assertTrue(pool.isClosed());
    }
  
    @Test
    public void checkJedisIsReusedWhenReturned() {
  
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort());
      Jedis jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.set("foo", "0");
      jedis.close();
  
      jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.incr("foo");
      jedis.close();
      pool.destroy();
      assertTrue(pool.isClosed());
    }
  
    @Test
    public void checkPoolRepairedWhenJedisIsBroken() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort());
      Jedis jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.quit();
      jedis.close();
  
      jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.incr("foo");
      jedis.close();
      pool.destroy();
      assertTrue(pool.isClosed());
    }
  
    @Test(expected = JedisConnectionException.class)
    public void checkPoolOverflow() {
      GenericObjectPoolConfig config = new GenericObjectPoolConfig();
      config.setMaxTotal(1);
      config.setBlockWhenExhausted(false);
      JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort());
      Jedis jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.set("foo", "0");
  
      Jedis newJedis = pool.getResource();
      newJedis.auth("foobared");
      newJedis.incr("foo");
    }
  
    @Test
    public void securePool() {
      JedisPoolConfig config = new JedisPoolConfig();
      config.setTestOnBorrow(true);
      JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(), 2000, "foobared");
      Jedis jedis = pool.getResource();
      jedis.set("foo", "bar");
      jedis.close();
      pool.destroy();
      assertTrue(pool.isClosed());
    }
  
    @Test
    public void nonDefaultDatabase() {
      JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000,
          "foobared");
      Jedis jedis0 = pool0.getResource();
      jedis0.set("foo", "bar");
      assertEquals("bar", jedis0.get("foo"));
      jedis0.close();
      pool0.destroy();
      assertTrue(pool0.isClosed());
  
      JedisPool pool1 = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000,
          "foobared", 1);
      Jedis jedis1 = pool1.getResource();
      assertNull(jedis1.get("foo"));
      jedis1.close();
      pool1.destroy();
      assertTrue(pool1.isClosed());
    }
  
    @Test
    public void startWithUrlString() {
      Jedis j = new Jedis("localhost", 6380);
      j.auth("foobared");
      j.select(2);
      j.set("foo", "bar");
      JedisPool pool = new JedisPool("redis://:foobared@localhost:6380/2");
      Jedis jedis = pool.getResource();
      assertEquals("PONG", jedis.ping());
      assertEquals("bar", jedis.get("foo"));
    }
  
    @Test
    public void startWithUrl() throws URISyntaxException {
      Jedis j = new Jedis("localhost", 6380);
      j.auth("foobared");
      j.select(2);
      j.set("foo", "bar");
      JedisPool pool = new JedisPool(new URI("redis://:foobared@localhost:6380/2"));
      Jedis jedis = pool.getResource();
      assertEquals("PONG", jedis.ping());
      assertEquals("bar", jedis.get("foo"));
    }
  
    @Test(expected = InvalidURIException.class)
    public void shouldThrowInvalidURIExceptionForInvalidURI() throws URISyntaxException {
      JedisPool pool = new JedisPool(new URI("localhost:6380"));
    }
  
    @Test
    public void allowUrlWithNoDBAndNoPassword() throws URISyntaxException {
      new JedisPool("redis://localhost:6380");
      new JedisPool(new URI("redis://localhost:6380"));
    }
  
    @Test
    public void selectDatabaseOnActivation() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000,
          "foobared");
  
      Jedis jedis0 = pool.getResource();
      assertEquals(0, jedis0.getDB());
  
      jedis0.select(1);
      assertEquals(1, jedis0.getDB());
  
      jedis0.close();
  
      Jedis jedis1 = pool.getResource();
      assertTrue("Jedis instance was not reused", jedis1 == jedis0);
      assertEquals(0, jedis1.getDB());
  
      jedis1.close();
      pool.destroy();
      assertTrue(pool.isClosed());
    }
  
    @Test
    public void customClientName() {
      JedisPool pool0 = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000,
          "foobared", 0, "my_shiny_client_name");
  
      Jedis jedis = pool0.getResource();
  
      assertEquals("my_shiny_client_name", jedis.clientGetname());
  
      jedis.close();
      pool0.destroy();
      assertTrue(pool0.isClosed());
    }
  
    @Test
    public void returnResourceDestroysResourceOnException() {
  
      class CrashingJedis extends Jedis {
        @Override
        public void resetState() {
          throw new RuntimeException();
        }
      }
  
      final AtomicInteger destroyed = new AtomicInteger(0);
  
      class CrashingJedisPooledObjectFactory implements PooledObjectFactory<Jedis> {
  
        @Override
        public PooledObject<Jedis> makeObject() throws Exception {
          return new DefaultPooledObject<Jedis>(new CrashingJedis());
        }
  
        @Override
        public void destroyObject(PooledObject<Jedis> p) throws Exception {
          destroyed.incrementAndGet();
        }
  
        @Override
        public boolean validateObject(PooledObject<Jedis> p) {
          return true;
        }
  
        @Override
        public void activateObject(PooledObject<Jedis> p) throws Exception {
        }
  
        @Override
        public void passivateObject(PooledObject<Jedis> p) throws Exception {
        }
      }
  
      GenericObjectPoolConfig config = new GenericObjectPoolConfig();
      config.setMaxTotal(1);
      JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(), 2000, "foobared");
      pool.initPool(config, new CrashingJedisPooledObjectFactory());
      Jedis crashingJedis = pool.getResource();
  
      try {
        crashingJedis.close();
      } catch (Exception ignored) {
      }
  
      assertEquals(destroyed.get(), 1);
    }
  
    @Test
    public void returnResourceShouldResetState() {
      GenericObjectPoolConfig config = new GenericObjectPoolConfig();
      config.setMaxTotal(1);
      config.setBlockWhenExhausted(false);
      JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(), 2000, "foobared");
  
      Jedis jedis = pool.getResource();
      try {
        jedis.set("hello", "jedis");
        Transaction t = jedis.multi();
        t.set("hello", "world");
      } finally {
        jedis.close();
      }
  
      Jedis jedis2 = pool.getResource();
      try {
        assertTrue(jedis == jedis2);
        assertEquals("jedis", jedis2.get("hello"));
      } finally {
        jedis2.close();
      }
  
      pool.destroy();
      assertTrue(pool.isClosed());
    }
  
    @Test
    public void checkResourceIsCloseable() {
      GenericObjectPoolConfig config = new GenericObjectPoolConfig();
      config.setMaxTotal(1);
      config.setBlockWhenExhausted(false);
      JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(), 2000, "foobared");
  
      Jedis jedis = pool.getResource();
      try {
        jedis.set("hello", "jedis");
      } finally {
        jedis.close();
      }
  
      Jedis jedis2 = pool.getResource();
      try {
        assertEquals(jedis, jedis2);
      } finally {
        jedis2.close();
      }
    }
  
    @Test
    public void getNumActiveIsNegativeWhenPoolIsClosed() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000,
          "foobared", 0, "my_shiny_client_name");
  
      pool.destroy();
      assertTrue(pool.getNumActive() < 0);
    }
  
    @Test
    public void getNumActiveReturnsTheCorrectNumber() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000);
      Jedis jedis = pool.getResource();
      jedis.auth("foobared");
      jedis.set("foo", "bar");
      assertEquals("bar", jedis.get("foo"));
  
      assertEquals(1, pool.getNumActive());
  
      Jedis jedis2 = pool.getResource();
      jedis.auth("foobared");
      jedis.set("foo", "bar");
  
      assertEquals(2, pool.getNumActive());
  
      jedis.close();
      assertEquals(1, pool.getNumActive());
  
      jedis2.close();
  
      assertEquals(0, pool.getNumActive());
  
      pool.destroy();
    }
  
    @Test
    public void testAddObject() {
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000);
      pool.addObjects(1);
      assertEquals(pool.getNumIdle(), 1);
      pool.destroy();
  
    }
  
    @Test
    public void testCloseConnectionOnMakeObject() {
      JedisPoolConfig config = new JedisPoolConfig();
      config.setTestOnBorrow(true);
      JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000, "wrong pass");
      Jedis jedis = new Jedis("redis://:foobared@localhost:6379/");
      int currentClientCount = getClientCount(jedis.clientList());
      try {
        pool.getResource();
        fail("Should throw exception as password is incorrect.");
      } catch (Exception e) {
        assertEquals(currentClientCount, getClientCount(jedis.clientList()));
      }
  
    }
  
    private int getClientCount(final String clientList) {
      return clientList.split("\n").length;
    }
  
  }
  