@Test
  public void testUpdateSealStatusWithMultipleDelegates() throws Exception {
    store.shutdown();
    ReplicaStatusDelegate mockReplicaStatusDelegate1 = mock(ReplicaStatusDelegate.class);
    ReplicaStatusDelegate mockReplicaStatusDelegate2 = mock(ReplicaStatusDelegate.class);
    when(mockReplicaStatusDelegate1.seal(any())).thenReturn(true);
    when(mockReplicaStatusDelegate1.unseal(any())).thenReturn(true);
    when(mockReplicaStatusDelegate1.partialSeal(any())).thenReturn(true);
    when(mockReplicaStatusDelegate2.seal(any())).thenReturn(true);
    when(mockReplicaStatusDelegate2.unseal(any())).thenReturn(true);
    when(mockReplicaStatusDelegate2.partialSeal(any())).thenReturn(true);
    properties.setProperty("store.replica.status.delegate.enable", "true");
    properties.setProperty("store.partial.write.enable.size.threshold.percentage", "50");
    StoreConfig config = new StoreConfig(new VerifiableProperties(properties));
    int storeUnsealPercentage = config.storePartialWriteEnableSizeThresholdPercentage
        - config.storePartialWriteToReadWriteEnableSizeThresholdPercentageDelta;
    MockReplicaId replicaId = getMockReplicaId(tempDirStr);
    List<ReplicaStatusDelegate> replicaStatusDelegates =
        Arrays.asList(mockReplicaStatusDelegate1, mockReplicaStatusDelegate2);
    storeMetrics = new StoreMetrics(new MetricRegistry());
    BlobStore testStore = createBlobStore(replicaId, config, replicaStatusDelegates, storeMetrics);
    PersistentIndex mockPersistentIndex = mock(PersistentIndex.class);
    testStore.index = mockPersistentIndex;
    // When store has usage higher than StoreConfig#storeReadOnlyEnableSizeThresholdPercentage
    // then replica seal status should be resolved as ReplicaSealStatus#Sealed.
    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storeReadOnlyEnableSizeThresholdPercentage) / 100 + 1);
    replicaId.setSealedState(ReplicaSealStatus.NOT_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 0, 0, 0, 0, 0, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 0, 0, 0, 0, 0, storeMetrics);

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storePartialWriteEnableSizeThresholdPercentage) / 100 + 1);
    replicaId.setSealedState(ReplicaSealStatus.NOT_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 2, 0, 0, 0, 0, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 4, 0, 0, 0, 0, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 4, 0, 0, 0, 0, storeMetrics);

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storePartialWriteEnableSizeThresholdPercentage) / 100 - 1);
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 4, 2, 0, 0, 0, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 2, 0, 0, 0, storeMetrics);

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn((LOG_CAPACITY * storeUnsealPercentage) / 100 - 1);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 0, 0, 0, storeMetrics);

    when(mockReplicaStatusDelegate1.seal(any())).thenReturn(false);
    when(mockReplicaStatusDelegate1.unseal(any())).thenReturn(false);
    when(mockReplicaStatusDelegate1.partialSeal(any())).thenReturn(false);
    when(mockReplicaStatusDelegate2.seal(any())).thenReturn(false);
    when(mockReplicaStatusDelegate2.unseal(any())).thenReturn(false);
    when(mockReplicaStatusDelegate2.partialSeal(any())).thenReturn(false);

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storeReadOnlyEnableSizeThresholdPercentage) / 100 + 1);
    replicaId.setSealedState(ReplicaSealStatus.NOT_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 2, 0, 0, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 4, 0, 0, storeMetrics);

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storePartialWriteEnableSizeThresholdPercentage) / 100 + 1);
    replicaId.setSealedState(ReplicaSealStatus.NOT_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 4, 2, 0, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 4, 4, 0, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 4, 6, 0, storeMetrics);

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storePartialWriteEnableSizeThresholdPercentage) / 100 - 1);
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 4, 6, 2, storeMetrics);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 4, 8, 2, storeMetrics);

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn((LOG_CAPACITY * storeUnsealPercentage) / 100 - 1);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(2, 6, 4, 4, 8, 4, storeMetrics);
  }
Test that if {@link HelixParticipant} is adopted, store state is set to OFFLINE after startup (which will be updated
by Helix state transition later)
@throws Exception
ambry-store/src/test/java/com/github/ambry/store/BlobStoreTest.java