@Test
  public void testRegisterInterestAndMakePrimaryWithFullRedundancy() {
    System.setProperty(GEMFIRE_PREFIX + "bridge.disableShufflingOfEndpoints", "true");

    createClientCache(3);
    createEntriesK1andK2();
    registerK1AndK2();

    assertThat(pool.getRedundantNames().size()).isEqualTo(3);

    vm0.invoke(this::verifyDispatcherIsAlive);
    vm1.invoke(this::verifyDispatcherIsNotAlive);
    vm2.invoke(this::verifyDispatcherIsNotAlive);
    vm3.invoke(this::verifyDispatcherIsNotAlive);

    for (VM vm : toArray(vm0, vm1, vm2, vm3)) {
      vm.invoke(this::verifyInterestRegistration);
    }

    PoolImpl.BEFORE_REGISTER_CALLBACK_FLAG = true;
    PoolImpl.BEFORE_PRIMARY_IDENTIFICATION_FROM_BACKUP_CALLBACK_FLAG = true;
    PoolImpl.BEFORE_RECOVER_INTEREST_CALLBACK_FLAG = true;
    registerInterestCalled.set(false);
    makePrimaryCalled.set(false);

    ClientServerObserverHolder.setInstance(new ClientServerObserverAdapter() {
      @Override
      public void beforeInterestRegistration() {
        registerInterestCalled.set(true);
      }

      @Override
      public void beforeInterestRecovery() {
        registerInterestCalled.set(true);
      }

      @Override
      public void beforePrimaryIdentificationFromBackup() {
        makePrimaryCalled.set(true);
      }
    });

    vm0.invoke(this::stopServer);
    doPuts();
    vm1.invoke(this::verifyDispatcherIsAlive);
    vm2.invoke(this::verifyDispatcherIsNotAlive);
    vm3.invoke(this::verifyDispatcherIsNotAlive);
    verifyConnectedAndRedundantServers(3, 2);

    assertThat(registerInterestCalled).describedAs(
        "register interest should not have been called since we failed to a redundant server")
        .isFalse();
    assertThat(makePrimaryCalled).describedAs(
        "make primary should have been called since primary did fail and a new primary was to be chosen")
        .isTrue();
    assertThat(pool.getRedundantNames().size()).isEqualTo(2);

    makePrimaryCalled.set(false);
    vm1.invoke(this::stopServer);
    doPuts();
    vm2.invoke(this::verifyDispatcherIsAlive);
    vm3.invoke(this::verifyDispatcherIsNotAlive);
    verifyConnectedAndRedundantServers(2, 1);

    assertThat(registerInterestCalled).describedAs(
        "register interest should not have been called since we failed to a redundant server")
        .isFalse();
    assertThat(makePrimaryCalled).describedAs(
        "make primary should have been called since primary did fail and a new primary was to be chosen")
        .isTrue();
    assertThat(pool.getRedundantNames().size()).isEqualTo(1);

    makePrimaryCalled.set(false);
    vm2.invoke(this::stopServer);
    doPuts();
    vm3.invoke(this::verifyDispatcherIsAlive);
    verifyConnectedAndRedundantServers(1, 0);

    assertThat(registerInterestCalled).describedAs(
        "register interest should not have been called since we failed to a redundant server")
        .isFalse();
    assertThat(makePrimaryCalled).describedAs(
        "make primary should have been called since primary did fail and a new primary was to be chosen")
        .isTrue();
    assertThat(pool.getRedundantNames().size()).isEqualTo(0);

    vm3.invoke(this::stopServer);
    vm0.invoke(this::startServer);
    verifyConnectedAndRedundantServers(1, 0);
    doPuts();
    vm0.invoke(this::verifyDispatcherIsAlive);
    vm0.invoke(this::verifyInterestRegistration);

    if (!registerInterestCalled.get()) {
      Assertions
          .fail("register interest should have been called since a recovered server came up");
    }
    assertThat(pool.getRedundantNames().size()).isEqualTo(0);

    PoolImpl.BEFORE_REGISTER_CALLBACK_FLAG = false;
    PoolImpl.BEFORE_PRIMARY_IDENTIFICATION_FROM_BACKUP_CALLBACK_FLAG = false;
    PoolImpl.BEFORE_RECOVER_INTEREST_CALLBACK_FLAG = false;
  }
This tests failing of a primary server in a situation where the rest of the server are all
redundant. After every failure, the order, the dispatcher, the interest registration and the
makePrimary calls are verified. The failure detection in these tests could be either through
CCU or cache operation, whichever occurs first
geode-core/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/RedundancyLevelPart3DUnitTest.java