@Test
  public void multiReplicaStatusDelegatesTest() throws Exception {
    Set<ReplicaId> sealedReplicas1 = new HashSet<>();
    ReplicaStatusDelegate mockDelegate1 = mock(ReplicaStatusDelegate.class);
    doAnswer(invocation -> {
      sealedReplicas1.add(invocation.getArgument(0));
      return true;
    }).when(mockDelegate1).seal(any());
    Set<ReplicaId> sealedReplicas2 = new HashSet<>();
    ReplicaStatusDelegate mockDelegate2 = mock(ReplicaStatusDelegate.class);
    doAnswer(invocation -> {
      sealedReplicas2.add(invocation.getArgument(0));
      return true;
    }).when(mockDelegate2).seal(any());
    doAnswer(invocation -> {
      sealedReplicas1.remove((ReplicaId) invocation.getArgument(0));
      return true;
    }).when(mockDelegate1).unseal(any());
    doAnswer(invocation -> {
      sealedReplicas2.remove((ReplicaId) invocation.getArgument(0));
      return true;
    }).when(mockDelegate2).unseal(any());
    doAnswer(invocation -> {
      sealedReplicas1.remove((ReplicaId) invocation.getArgument(0));
      return true;
    }).when(mockDelegate1).partialSeal(any());
    doAnswer(invocation -> {
      sealedReplicas2.remove((ReplicaId) invocation.getArgument(0));
      return true;
    }).when(mockDelegate2).partialSeal(any());
    doAnswer(
        invocation -> sealedReplicas1.stream().map(r -> r.getPartitionId().toPathString()).collect(Collectors.toList()))
        .when(mockDelegate1)
        .getSealedReplicas();
    doAnswer(
        invocation -> sealedReplicas2.stream().map(r -> r.getPartitionId().toPathString()).collect(Collectors.toList()))
        .when(mockDelegate2)
        .getSealedReplicas();
    StoreConfig defaultConfig = changeThreshold(65, 5, true);
    MockReplicaId replicaId = getMockReplicaId(tempDirStr);
    reloadStore(defaultConfig, replicaId, Arrays.asList(mockDelegate1, mockDelegate2));
    // make the replica sealed
    put(4, (long) (SEGMENT_CAPACITY * 0.8), Utils.Infinite_Time);
    assertEquals("Sealed replica lists are different", sealedReplicas1, sealedReplicas2);
    assertEquals("Sealed replica is not correct", replicaId, sealedReplicas1.iterator().next());
    // try to bump the readonly threshold so as to unseal the replica
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    reloadStore(changeThreshold(99, 1, true), replicaId, Arrays.asList(mockDelegate1, mockDelegate2));
    assertTrue("Replica should be unsealed", sealedReplicas1.isEmpty() && sealedReplicas2.isEmpty());
    assertEquals("After startup, store should be in STANDBY state", STANDBY, store.getCurrentState());

    // verify store still updates sealed lists even though replica state is already sealed. ("replicaId.setSealedState(true)")
    // lower the threshold to make replica sealed again
    reloadStore(changeThreshold(50, 5, true), replicaId, Arrays.asList(mockDelegate1, mockDelegate2));
    assertEquals("Sealed replica lists are different", sealedReplicas1, sealedReplicas2);
    assertEquals("Sealed replica is not correct", replicaId, sealedReplicas1.iterator().next());

    // verify reconciliation case: we make read-write delta a wide range and clear sealedReplicas2 to make them reconcile
    sealedReplicas2.clear();
    reloadStore(changeThreshold(99, 90, true), replicaId, Arrays.asList(mockDelegate1, mockDelegate2));
    assertEquals("Sealed replica lists are different", sealedReplicas1, sealedReplicas2);
    assertEquals("Sealed replica is not correct", replicaId, sealedReplicas2.iterator().next());
    store.shutdown();
  }
Test store is able to correctly seal/unseal replica with multiple participants.
@throws Exception
ambry-store/src/test/java/com/github/ambry/store/BlobStoreTest.java