private void createClientCache(int redundancy, int socketReadTimeout, int retryInterval) {
    if (!failOverDetectionByCCU.get()) {
      clientServerObserver =
          ClientServerObserverHolder.setInstance(new ClientServerObserverAdapter() {
            @Override
            public void beforeFailoverByCacheClientUpdater(ServerLocation epFailed) {
              try {
                latch.await(TIMEOUT_MILLIS, MILLISECONDS);
              } catch (InterruptedException ie) {
                // expected - test will shut down the cache which will interrupt
                // the CacheClientUpdater thread that invoked this method
                Thread.currentThread().interrupt();
              }
            }
          });
    }

    Properties props = new Properties();
    props.setProperty(MCAST_PORT, "0");
    props.setProperty(LOCATORS, "");

    cache = cacheRule.getOrCreateCache(props);

    pool = (PoolImpl) PoolManager.createFactory()
        .addServer(hostname, port0)
        .addServer(hostname, port1)
        .addServer(hostname, port2)
        .addServer(hostname, port3)
        .setSubscriptionEnabled(true)
        .setReadTimeout(socketReadTimeout)
        .setSocketBufferSize(32768)
        .setMinConnections(8)
        .setSubscriptionRedundancy(redundancy)
        .setRetryAttempts(5)
        .setPingInterval(retryInterval)
        .create("DurableClientReconnectDUnitTestPool");

    cache.createRegionFactory()
        .setScope(Scope.DISTRIBUTED_ACK)
        .setPoolName(pool.getName())
        .create(REGION_NAME);

    createEntriesK1andK2();
    registerK1AndK2();
  }
Redundancy level specified & less than total Eps. If an EP dies & is part of the fail over list
, then it should be removed from live server map & added to dead server map. A new EP should be
picked from the Live Server Map to compensate for the failure. Failure Detection by Put
operation.
geode-core/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/RedundancyLevelPart1DUnitTest.java