private void assertFileRestoreFromWAL() throws IOException {
    paginatedCluster.close();
    writeAheadLog.close();

    readCache.clear();

    restoreClusterFromWAL();

    testCluster.close();

    assertClusterContentIsTheSame(testCluster.getName(), paginatedCluster.getName());

    testCluster.open();
    paginatedCluster.open();
  }
  @AfterMethod
  public void afterMethod() throws IOException {
    Assert.assertNull(atomicOperationsManager.getCurrentOperation());

    writeAheadLog.delete();
    readCache.deleteStorage(writeCache);

    testCluster.delete();
    testReadCache.deleteStorage(testWriteCache);

    File file = new File(storageDir);
    Assert.assertTrue(file.delete());

    file = new File(testStorageDir);
    Assert.assertTrue(file.delete());

    file = new File(buildDirectory);
    Assert.assertTrue(file.delete());
  }
  private void restoreClusterFromWAL() throws IOException {
    ODiskWriteAheadLog log =
        new ODiskWriteAheadLog(4, -1, 10 * 1024L * OWALPage.PAGE_SIZE, storage);
    OLogSequenceNumber lsn = log.begin();

    List<OWALRecord> atomicUnit = new ArrayList<OWALRecord>();

    boolean atomicChangeIsProcessed = false;
    while (lsn != null) {
      OWALRecord walRecord = log.read(lsn);
      atomicUnit.add(walRecord);

      if (!atomicChangeIsProcessed) {
        Assert.assertTrue(walRecord instanceof OAtomicUnitStartRecord);
        atomicChangeIsProcessed = true;
      } else if (walRecord instanceof OAtomicUnitEndRecord) {
        atomicChangeIsProcessed = false;

        for (OWALRecord restoreRecord : atomicUnit) {
          if (restoreRecord instanceof OAtomicUnitStartRecord
              || restoreRecord instanceof OAtomicUnitEndRecord
              || restoreRecord instanceof OFileCreatedWALRecord
              || restoreRecord instanceof ONonTxOperationPerformedWALRecord) continue;

          final OUpdatePageRecord updatePageRecord = (OUpdatePageRecord) restoreRecord;

          final long fileId = updatePageRecord.getFileId();
          final long pageIndex = updatePageRecord.getPageIndex();

          if (!testWriteCache.isOpen(fileId)) testReadCache.openFile(fileId, testWriteCache);

          OCacheEntry cacheEntry = testReadCache.load(fileId, pageIndex, true, testWriteCache);
          if (cacheEntry == null) {
            do {
              if (cacheEntry != null) readCache.release(cacheEntry, testWriteCache);

              cacheEntry = testReadCache.allocateNewPage(fileId, testWriteCache);
            } while (cacheEntry.getPageIndex() != pageIndex);
          }
          cacheEntry.acquireExclusiveLock();
          try {
            ODurablePage durablePage = new ODurablePage(cacheEntry, null);
            durablePage.restoreChanges(updatePageRecord.getChanges());
            durablePage.setLsn(updatePageRecord.getLsn());

            cacheEntry.markDirty();
          } finally {
            cacheEntry.releaseExclusiveLock();
            testReadCache.release(cacheEntry, testWriteCache);
          }
        }
        atomicUnit.clear();
      } else {
        Assert.assertTrue(
            walRecord instanceof OUpdatePageRecord
                || walRecord instanceof OFileCreatedWALRecord
                || walRecord instanceof ONonTxOperationPerformedWALRecord);
      }

      lsn = log.next(lsn);
    }

    Assert.assertTrue(atomicUnit.isEmpty());
    log.close();
  }