@Test
public void recover()
    throws IOException, StorageEngineException, InterruptedException, IllegalPathException {

  receiverLogger = new SyncReceiverLogger(
      new File(getReceiverFolderFile(), SyncConstant.SYNC_LOG_NAME));
  fileLoader = FileLoader.createFileLoader(getReceiverFolderFile());
  Map<String, Set<File>> allFileList = new HashMap<>();
  Map<String, Set<File>> correctSequenceLoadedFileMap = new HashMap<>();
  // add some new tsfiles
  Random r = new Random(0);
  receiverLogger.startSyncTsFiles();
  Set<String> toBeSyncedFiles = new HashSet<>();
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 10; j++) {
      allFileList.putIfAbsent(SG_NAME + i, new HashSet<>());
      correctSequenceLoadedFileMap.putIfAbsent(SG_NAME + i, new HashSet<>());
      String rand = String.valueOf(r.nextInt(10000) + i * j);
      String fileName =
          getSnapshotFolder() + File.separator + SG_NAME + i + File.separator + System
              .currentTimeMillis() + IoTDBConstant.FILE_NAME_SEPARATOR + rand
              + IoTDBConstant.FILE_NAME_SEPARATOR + "0.tsfile";
      Thread.sleep(1);
      File syncFile = new File(fileName);
      receiverLogger
          .finishSyncTsfile(syncFile);
      toBeSyncedFiles.add(syncFile.getAbsolutePath());
      File dataFile = new File(
          DirectoryManager.getInstance().getNextFolderForSequenceFile(),
          syncFile.getParentFile().getName() + File.separatorChar
              + syncFile.getName());
      correctSequenceLoadedFileMap.get(SG_NAME + i).add(dataFile);
      allFileList.get(SG_NAME + i).add(syncFile);
      if (!syncFile.getParentFile().exists()) {
        syncFile.getParentFile().mkdirs();
      }
      if (!syncFile.exists() && !syncFile.createNewFile()) {
        LOGGER.error("Can not create new file {}", syncFile.getPath());
      }
      if (!new File(syncFile.getAbsolutePath() + TsFileResource.RESOURCE_SUFFIX).exists()
          && !new File(syncFile.getAbsolutePath() + TsFileResource.RESOURCE_SUFFIX)
          .createNewFile()) {
        LOGGER.error("Can not create new file {}", syncFile.getPath());
      }
      TsFileResource tsFileResource = new TsFileResource(syncFile);
      tsFileResource.putStartTime(String.valueOf(i), (long) j * 10);
      tsFileResource.putEndTime(String.valueOf(i), (long) j * 10 + 5);
      tsFileResource.serialize();
    }
  }
  for (int i = 0; i < 3; i++) {
    StorageGroupProcessor processor = StorageEngine.getInstance().getProcessor(new PartialPath(SG_NAME + i));
    assertTrue(processor.getSequenceFileTreeSet().isEmpty());
    assertTrue(processor.getUnSequenceFileList().isEmpty());
  }
  assertTrue(getReceiverFolderFile().exists());
  for (Set<File> set : allFileList.values()) {
    for (File newTsFile : set) {
      if (!newTsFile.getName().endsWith(TsFileResource.RESOURCE_SUFFIX)) {
        fileLoader.addTsfile(newTsFile);
      }
    }
  }
  receiverLogger.close();
  assertTrue(new File(getReceiverFolderFile(), SyncConstant.LOAD_LOG_NAME).exists());
  assertTrue(new File(getReceiverFolderFile(), SyncConstant.SYNC_LOG_NAME).exists());
  assertTrue(
      FileLoaderManager.getInstance().containsFileLoader(getReceiverFolderFile().getName()));
  int mode = 0;
  Set<String> toBeSyncedFilesTest = new HashSet<>();
  try (BufferedReader br = new BufferedReader(
      new FileReader(new File(getReceiverFolderFile(), SyncConstant.SYNC_LOG_NAME)))) {
    String line;
    while ((line = br.readLine()) != null) {
      if (line.equals(SyncReceiverLogger.SYNC_DELETED_FILE_NAME_START)) {
        mode = -1;
      } else if (line.equals(SyncReceiverLogger.SYNC_TSFILE_START)) {
        mode = 1;
      } else {
        if (mode == 1) {
          toBeSyncedFilesTest.add(line);
        }
      }
    }
  }
  assertEquals(toBeSyncedFilesTest.size(), toBeSyncedFiles.size());
  assertTrue(toBeSyncedFilesTest.containsAll(toBeSyncedFiles));
  logAnalyze.recover(getReceiverFolderFile().getName());
  try {
    long waitTime = 0;
    while (FileLoaderManager.getInstance()
        .containsFileLoader(getReceiverFolderFile().getName())) {
      Thread.sleep(100);
      waitTime += 100;
      LOGGER.info("Has waited for loading new tsfiles {}ms", waitTime);
    }
  } catch (InterruptedException e) {
    LOGGER.error("Fail to wait for loading new tsfiles", e);
    Thread.currentThread().interrupt();
    throw e;
  }
  assertFalse(new File(getReceiverFolderFile(), SyncConstant.LOAD_LOG_NAME).exists());
  assertFalse(new File(getReceiverFolderFile(), SyncConstant.SYNC_LOG_NAME).exists());
}