@Test
  public void testUpdateSealStatusWithSingleDelegate() throws Exception {
    store.shutdown();
    ReplicaStatusDelegate mockReplicaStatusDelegate = mock(ReplicaStatusDelegate.class);
    when(mockReplicaStatusDelegate.seal(any())).thenReturn(true);
    when(mockReplicaStatusDelegate.unseal(any())).thenReturn(true);
    when(mockReplicaStatusDelegate.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);
    storeMetrics = new StoreMetrics(new MetricRegistry());
    BlobStore testStore =
        createBlobStore(replicaId, config, Collections.singletonList(mockReplicaStatusDelegate), storeMetrics);
    PersistentIndex mockPersistentIndex = mock(PersistentIndex.class);
    testStore.index = mockPersistentIndex;
    // When store has usage higher than StoreConfig#storeReadOnlyEnableSizeThresholdPercentage
    // and replica is not sealed then seal should be attempted.
    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storeReadOnlyEnableSizeThresholdPercentage) / 100 + 1);
    replicaId.setSealedState(ReplicaSealStatus.NOT_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 0, 0, 0, 0, 0, storeMetrics);

    // When store has usage higher than StoreConfig#storeReadOnlyEnableSizeThresholdPercentage
    // and replica is already sealed then seal should not be attempted.
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 0, 0, 0, 0, 0, storeMetrics);

    // When store has usage higher than StoreConfig#storePartialWriteEnableSizeThresholdPercentage
    // and replica is not sealed then partial seal should be attempted.
    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storePartialWriteEnableSizeThresholdPercentage) / 100 + 1);
    replicaId.setSealedState(ReplicaSealStatus.NOT_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 1, 0, 0, 0, 0, storeMetrics);

    // When store has usage higher than StoreConfig#storePartialWriteEnableSizeThresholdPercentage
    // and replica is sealed then partial seal should be attempted.
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 2, 0, 0, 0, 0, storeMetrics);

    // When store has usage higher than StoreConfig#storePartialWriteEnableSizeThresholdPercentage
    // and replica is partially sealed then partial seal should not be attempted.
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 2, 0, 0, 0, 0, storeMetrics);

    // When store has usage lower than StoreConfig#storePartialWriteEnableSizeThresholdPercentage
    // and replica is sealed then unseal should be attempted.
    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn(
        (LOG_CAPACITY * config.storePartialWriteEnableSizeThresholdPercentage) / 100 - 1);
    replicaId.setSealedState(ReplicaSealStatus.SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 2, 1, 0, 0, 0, storeMetrics);

    // When replica is partially sealed and store has usage lower than
    // StoreConfig#storePartialWriteEnableSizeThresholdPercentage but the difference is less than
    // StoreConfig#storePartialWriteToReadWriteEnableSizeThresholdPercentageDelta then unseal should not
    // be attempted.
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 2, 1, 0, 0, 0, storeMetrics);

    // When store has usage lower than StoreConfig#storePartialWriteEnableSizeThresholdPercentage
    // and replica is partially sealed then unseal should be attempted.
    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn((LOG_CAPACITY * storeUnsealPercentage) / 100 - 1);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 2, 2, 0, 0, 0, storeMetrics);

    // Test for failure scenarios. For failures, the attempts should increase everytime.
    when(mockReplicaStatusDelegate.seal(any())).thenReturn(false);
    when(mockReplicaStatusDelegate.unseal(any())).thenReturn(false);
    when(mockReplicaStatusDelegate.partialSeal(any())).thenReturn(false);

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

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

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

    when(mockPersistentIndex.getLogUsedCapacity()).thenReturn((LOG_CAPACITY * storeUnsealPercentage) / 100 - 1);
    replicaId.setSealedState(ReplicaSealStatus.PARTIALLY_SEALED);
    testStore.updateSealedStatus();
    verifySealMetrics(1, 2, 2, 1, 2, 2, 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