content: package redis.clients.jedis.tests;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import org.junit.After;
  import org.junit.Before;
  import org.junit.Test;
  
  import redis.clients.jedis.HostAndPort;
  import redis.clients.jedis.Jedis;
  import redis.clients.jedis.exceptions.JedisDataException;
  import redis.clients.jedis.tests.utils.JedisSentinelTestUtil;
  
  public class JedisSentinelTest extends JedisTestBase {
    private static final String MASTER_NAME = "mymaster";
    private static final String MONITOR_MASTER_NAME = "mymastermonitor";
    private static final String REMOVE_MASTER_NAME = "mymasterremove";
    private static final String FAILOVER_MASTER_NAME = "mymasterfailover";
    private static final String MASTER_IP = "127.0.0.1";
  
    protected static HostAndPort master = HostAndPortUtil.getRedisServers().get(0);
    protected static HostAndPort slave = HostAndPortUtil.getRedisServers().get(4);
    protected static HostAndPort sentinel = HostAndPortUtil.getSentinelServers().get(0);
  
    protected static HostAndPort sentinelForFailover = HostAndPortUtil.getSentinelServers().get(2);
    protected static HostAndPort masterForFailover = HostAndPortUtil.getRedisServers().get(5);
  
    @Before
    public void setup() throws InterruptedException {
    }
  
    @After
    public void clear() throws InterruptedException {
      // New Sentinel (after 2.8.1)
      // when slave promoted to master (slave of no one), New Sentinel force
      // to restore it (demote)
      // so, promote(slaveof) slave to master has no effect, not same to old
      // Sentinel's behavior
      ensureRemoved(MONITOR_MASTER_NAME);
      ensureRemoved(REMOVE_MASTER_NAME);
    }
  
    @Test
    public void sentinel() {
      Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
  
      try {
        List<Map<String, String>> masters = j.sentinelMasters();
  
        boolean inMasters = false;
        for (Map<String, String> master : masters)
          if (MASTER_NAME.equals(master.get("name"))) inMasters = true;
  
        assertTrue(inMasters);
  
        List<String> masterHostAndPort = j.sentinelGetMasterAddrByName(MASTER_NAME);
        HostAndPort masterFromSentinel = new HostAndPort(masterHostAndPort.get(0),
            Integer.parseInt(masterHostAndPort.get(1)));
        assertEquals(master, masterFromSentinel);
  
        List<Map<String, String>> slaves = j.sentinelSlaves(MASTER_NAME);
        assertTrue(slaves.size() > 0);
        assertEquals(master.getPort(), Integer.parseInt(slaves.get(0).get("master-port")));
  
        // DO NOT RE-RUN TEST TOO FAST, RESET TAKES SOME TIME TO... RESET
        assertEquals(Long.valueOf(1), j.sentinelReset(MASTER_NAME));
        assertEquals(Long.valueOf(0), j.sentinelReset("woof" + MASTER_NAME));
      } finally {
        j.close();
      }
    }
  
    @Test
    public void sentinelFailover() throws InterruptedException {
      Jedis j = new Jedis(sentinelForFailover.getHost(), sentinelForFailover.getPort());
      Jedis j2 = new Jedis(sentinelForFailover.getHost(), sentinelForFailover.getPort());
  
      try {
        List<String> masterHostAndPort = j.sentinelGetMasterAddrByName(FAILOVER_MASTER_NAME);
        HostAndPort currentMaster = new HostAndPort(masterHostAndPort.get(0),
            Integer.parseInt(masterHostAndPort.get(1)));
  
        JedisSentinelTestUtil.waitForNewPromotedMaster(FAILOVER_MASTER_NAME, j, j2);
  
        masterHostAndPort = j.sentinelGetMasterAddrByName(FAILOVER_MASTER_NAME);
        HostAndPort newMaster = new HostAndPort(masterHostAndPort.get(0),
            Integer.parseInt(masterHostAndPort.get(1)));
  
        assertNotEquals(newMaster, currentMaster);
      } finally {
        j.close();
      }
  
    }
  
    @Test
    public void sentinelMonitor() {
      Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
  
      try {
        // monitor new master
        String result = j.sentinelMonitor(MONITOR_MASTER_NAME, MASTER_IP, master.getPort(), 1);
        assertEquals("OK", result);
  
        // already monitored
        try {
          j.sentinelMonitor(MONITOR_MASTER_NAME, MASTER_IP, master.getPort(), 1);
          fail();
        } catch (JedisDataException e) {
          // pass
        }
      } finally {
        j.close();
      }
    }
  
    @Test
    public void sentinelRemove() {
      Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
  
      try {
        ensureMonitored(sentinel, REMOVE_MASTER_NAME, MASTER_IP, master.getPort(), 1);
  
        String result = j.sentinelRemove(REMOVE_MASTER_NAME);
        assertEquals("OK", result);
  
        // not exist
        try {
          result = j.sentinelRemove(REMOVE_MASTER_NAME);
          assertNotEquals("OK", result);
          fail();
        } catch (JedisDataException e) {
          // pass
        }
      } finally {
        j.close();
      }
    }
  
    @Test
    public void sentinelSet() {
      Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
  
      try {
        Map<String, String> parameterMap = new HashMap<String, String>();
        parameterMap.put("down-after-milliseconds", String.valueOf(1234));
        parameterMap.put("parallel-syncs", String.valueOf(3));
        parameterMap.put("quorum", String.valueOf(2));
        j.sentinelSet(MASTER_NAME, parameterMap);
  
        List<Map<String, String>> masters = j.sentinelMasters();
        for (Map<String, String> master : masters) {
          if (master.get("name").equals(MASTER_NAME)) {
            assertEquals(1234, Integer.parseInt(master.get("down-after-milliseconds")));
            assertEquals(3, Integer.parseInt(master.get("parallel-syncs")));
            assertEquals(2, Integer.parseInt(master.get("quorum")));
          }
        }
  
        parameterMap.put("quorum", String.valueOf(1));
        j.sentinelSet(MASTER_NAME, parameterMap);
      } finally {
        j.close();
      }
    }
  
    private void ensureMonitored(HostAndPort sentinel, String masterName, String ip, int port,
        int quorum) {
      Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
      try {
        j.sentinelMonitor(masterName, ip, port, quorum);
      } catch (JedisDataException e) {
      } finally {
        j.close();
      }
    }
  
    private void ensureRemoved(String masterName) {
      Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
      try {
        j.sentinelRemove(masterName);
      } catch (JedisDataException e) {
      } finally {
        j.close();
      }
    }
  
  }
  