@Test
  public void subsequentStartupTest() throws Exception {
    requiredSwapSegmentsPerSize = 1;
    alloc = constructAllocator();
    List<DiskSpaceRequirements> requirementsList = new ArrayList<>();

    requirementsList.add(new DiskSpaceRequirements(storeId0, 5, 6, 0));
    requirementsList.add(new DiskSpaceRequirements(storeId1, 3, 7, 0));
    requirementsList.add(new DiskSpaceRequirements(storeId2, 5, 4, 0));
    alloc.initializePool(requirementsList);
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 5, 6)
        .addStoreSeg(storeId1, 3, 7)
        .addStoreSeg(storeId2, 5, 4)
        .addSwapSeg(5, 1)
        .addSwapSeg(3, 1));
    File f1 = allocateAndVerify(storeId0, "file1", 5, false);
    File f2 = allocateAndVerify(storeId1, "file2", 3, false);
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 5, 5)
        .addStoreSeg(storeId1, 3, 6)
        .addStoreSeg(storeId2, 5, 4)
        .addSwapSeg(5, 1)
        .addSwapSeg(3, 1));
    // second startup, test freeing old files after initialization
    alloc = constructAllocator();
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 5, 5)
        .addStoreSeg(storeId1, 3, 6)
        .addStoreSeg(storeId2, 5, 4)
        .addSwapSeg(5, 1)
        .addSwapSeg(3, 1));
    alloc.initializePool(requirementsList);
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 5, 6)
        .addStoreSeg(storeId1, 3, 7)
        .addStoreSeg(storeId2, 5, 4)
        .addSwapSeg(5, 1)
        .addSwapSeg(3, 1));
    freeAndVerify(storeId0, f1, 5, false);
    freeAndVerify(storeId1, f2, 3, false);
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 5, 7)
        .addStoreSeg(storeId1, 3, 8)
        .addStoreSeg(storeId2, 5, 4)
        .addSwapSeg(5, 1)
        .addSwapSeg(3, 1));
    // third startup, test allocating files before initialization and changing disk space requirements when initializing
    alloc = constructAllocator();
    f1 = allocateAndVerify(storeId1, "file1", 3, false);
    f2 = allocateAndVerify(storeId2, "file2", 5, false);
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 5, 7)
        .addStoreSeg(storeId1, 3, 7)
        .addStoreSeg(storeId2, 5, 3)
        .addSwapSeg(5, 1)
        .addSwapSeg(3, 1));
    // files freed before init should be discarded, not returned to the pool
    freeAndVerify(storeId1, f1, 3, false);
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 5, 7)
        .addStoreSeg(storeId1, 3, 7)
        .addStoreSeg(storeId2, 5, 3)
        .addSwapSeg(5, 1)
        .addSwapSeg(3, 1));
    requirementsList.clear();
    requirementsList.add(new DiskSpaceRequirements(storeId0, 3, 20, 1));
    requirementsList.add(new DiskSpaceRequirements(storeId1, 5, 6, 1));
    requirementsList.add(new DiskSpaceRequirements(storeId2, 6, 1, 1));
    alloc.initializePool(requirementsList);
    verifyPoolState(
        new ExpectedState().addStoreSeg(storeId0, 3, 20).addStoreSeg(storeId1, 5, 6).addStoreSeg(storeId2, 6, 1));
    freeAndVerify(storeId2, f2, 5, false);
    verifyPoolState(new ExpectedState().addStoreSeg(storeId0, 3, 20)
        .addStoreSeg(storeId1, 5, 6)
        .addStoreSeg(storeId2, 6, 1)
        .addStoreSeg(storeId2, 5, 1));
  }
This tests various cases where the allocator is restarted and disk space requirements change.
@throws Exception
ambry-store/src/test/java/com/github/ambry/store/DiskSpaceAllocatorTest.java