public void testGetStoreEntry() throws Exception {
    cleanUpDataFolder();
    LocalHistoryTestStore store = createStore();
    LogHandler lh = new LogHandler("copied file", LogHandler.Compare.STARTS_WITH);

    File folder = dataDir;
    folder.mkdirs();
    File file1 = new File(folder, "file1");
    File file2 = new File(folder, "file2");

    createFile(store, file1, System.currentTimeMillis(), "data1");
    createFile(store, file2, System.currentTimeMillis(), "data2");

    // change the file
    lh.reset();
    changeFile(store, file1, System.currentTimeMillis(), "data1.1");
    lh.waitUntilDone();

    // rewrite the file
    write(file1, "data1.2".getBytes());
    assertDataInFile(file1, "data1.2".getBytes());

    // get the files last state
    StoreEntry entry = store.getStoreEntry(file1, System.currentTimeMillis());
    assertNotNull(entry);
    assertDataInStream(entry.getStoreFileInputStream(), "data1.1".getBytes());
  }
  public void testFileChange() throws Exception {
    LocalHistoryTestStore store = createStore();
    LogHandler lh = new LogHandler("copied file", LogHandler.Compare.STARTS_WITH);

    long ts = System.currentTimeMillis();

    // create file in store
    File file = new File(dataDir, "file1");
    createFile(store, file, ts, "data");

    File storefile = store.getStoreFile(file, ts, false);
    // change file with same ts
    // XXX
    //        if(store.lastModified(file) != ts) {
    //            changeFile(store, file, ts, "data2");
    //        }
    // check that nothing changed
    assertFile(file, store, ts, storefile.lastModified(), 1, 1, "data", TOUCHED);

    // change file with new ts
    ts = System.currentTimeMillis();
    lh.reset();
    changeFile(store, file, ts, "data2");
    lh.waitUntilDone();

    // check the change
    assertFile(file, store, ts, -1, 2, 1, "data2", TOUCHED);
  }
  public void testGetDeletedFiles() throws Exception {
    cleanUpDataFolder();
    LocalHistoryTestStore store = createStore();
    LogHandler lh = new LogHandler("copied file", LogHandler.Compare.STARTS_WITH);

    cleanUpDataFolder();
    File folder = dataDir;
    folder.mkdirs();

    // create the files
    File file1 = new File(folder, "file1");
    File file2 = new File(folder, "file2");
    File file3 = new File(folder, "file3");
    File file4 = new File(folder, "file4");

    createFile(store, file1, System.currentTimeMillis(), "data1");
    createFile(store, file2, System.currentTimeMillis(), "data2");
    createFile(store, file3, System.currentTimeMillis(), "data3");
    createFile(store, file4, System.currentTimeMillis(), "data4");

    // touch the files
    lh.reset();
    changeFile(store, file1, System.currentTimeMillis(), "data1.1");
    lh.waitUntilDone();
    lh.reset();
    changeFile(store, file2, System.currentTimeMillis(), "data2.1");
    lh.waitUntilDone();
    lh.reset();
    changeFile(store, file3, System.currentTimeMillis(), "data3.1");
    lh.waitUntilDone();
    lh.reset();
    changeFile(store, file4, System.currentTimeMillis(), "data4.1");
    lh.waitUntilDone();

    // delete one of them
    store.fileDelete(file2, System.currentTimeMillis());
    StoreEntry[] entries = store.getDeletedFiles(folder);
    assertEntries(entries, new File[] {file2}, new String[] {"data2.1"});

    // delete one of them
    store.fileDelete(file3, System.currentTimeMillis());
    entries = store.getDeletedFiles(folder);
    assertEntries(entries, new File[] {file2, file3}, new String[] {"data2.1", "data3.1"});

    // delete without entry - only via .delete()
    file4.delete();
    entries = store.getDeletedFiles(folder);
    assertEntries(
        entries, new File[] {file2, file3, file4}, new String[] {"data2.1", "data3.1", "data4.1"});
  }
  public void testDeleteEntry() throws Exception {
    LocalHistoryTestStore store = createStore();
    LogHandler lh = new LogHandler("copied file", LogHandler.Compare.STARTS_WITH);

    File folder = new File(dataDir, "datafolder");
    folder.mkdirs();

    // create the file
    File file1 = new File(folder, "file1");

    // lets create some history
    long ts = System.currentTimeMillis() - 4 * 24 * 60 * 60 * 1000;
    createFile(store, file1, ts + 1000, "data1");
    lh.reset();
    changeFile(store, file1, ts + 2000, "data1.1");
    lh.waitUntilDone();
    lh.reset();
    changeFile(store, file1, ts + 3000, "data1.2");
    lh.waitUntilDone();

    StoreEntry[] se = store.getStoreEntries(file1);
    assertEntries(
        se,
        file1,
        new long[] {ts + 1000, ts + 2000, ts + 3000},
        new String[] {"data1", "data1.1", "data1.2"});

    // delete an entry
    store.deleteEntry(file1, ts + 2000);
    se = store.getStoreEntries(file1);
    assertEntries(se, file1, new long[] {ts + 1000, ts + 3000}, new String[] {"data1", "data1.2"});

    store.deleteEntry(file1, ts + 3000);
    se = store.getStoreEntries(file1);
    assertEntries(se, file1, new long[] {ts + 1000}, new String[] {"data1"});

    store.deleteEntry(file1, ts + 1000);
    se = store.getStoreEntries(file1);
    assertEquals(se.length, 0);
  }
  public void testNoEntryInZipStoreFile() throws Exception {
    final LocalHistoryTestStore store = createStore();
    final LogHandler lhBlock =
        new LogHandler("created storage file", LogHandler.Compare.STARTS_WITH);
    LogHandler lh = new LogHandler("finnished copy file", LogHandler.Compare.STARTS_WITH);
    ExceptionHandler h = new ExceptionHandler();

    final long ts = System.currentTimeMillis();
    final File file = new File(dataDir, "file");
    final Exception[] e = new Exception[1];
    final boolean event[] = new boolean[] {false};
    store.addVersioningListener(
        new VersioningListener() {
          @Override
          public void versioningEvent(VersioningEvent evt) {
            event[0] = true;
            StoreEntry entry = store.getStoreEntry(file, ts);
            try {
              entry.getStoreFileOutputStream();
            } catch (IOException ex) {
              e[0] = ex;
            }
          }
        });

    lhBlock.block(
        1000000); // start blocking so that we can try to access after created, but before filed
                  // with data
    changeFile(store, file, ts, "data2");
    long ts1 = System.currentTimeMillis();
    while (!event[0] && !(System.currentTimeMillis() - ts1 < 10000)) {
      Thread.sleep(200);
    }
    lhBlock.unblock();
    lh.waitUntilDone();
  }
  private long setupFirstFolderToRevert(LocalHistoryStore store, File folder) throws Exception {
    LogHandler lh = new LogHandler("copied file", LogHandler.Compare.STARTS_WITH);

    File fileNotInStorage = new File(folder, "fileNotInStorage");
    File fileUnchanged = new File(folder, "fileUnchanged");
    File fileChangedAfterRevert = new File(folder, "fileChangedAfterRevert");
    File fileDeletedAfterRevert = new File(folder, "fileDeletedAfterRevert");
    File fileDeletedBeforeRevert = new File(folder, "fileDeletedBeforeRevert");
    File fileUndeletedBeforeRevert = new File(folder, "fileUndeletedBeforeRevert");
    File fileCreatedAfterRevert = new File(folder, "fileCreatedAfterRevert");

    File folderDeletedAfterRevert = new File(folder, "folderDeletedAfterRevert");
    File folderCreatedAfterRevert = new File(folder, "folderCreatedAfterRevert");

    createFile(store, folder, System.currentTimeMillis(), null);
    write(fileNotInStorage, "fileNotInStorage".getBytes());
    createFile(store, fileUnchanged, System.currentTimeMillis(), "fileUnchanged");
    createFile(
        store,
        fileChangedAfterRevert,
        System.currentTimeMillis(),
        "fileChangedAfterRevert BEFORE change");
    createFile(
        store,
        fileDeletedAfterRevert,
        System.currentTimeMillis(),
        "fileDeletedAfterRevert BEFORE delete");
    createFile(
        store,
        fileDeletedBeforeRevert,
        System.currentTimeMillis(),
        "fileDeletedBeforeRevert BEFORE delete");
    createFile(
        store, fileUndeletedBeforeRevert, System.currentTimeMillis(), "fileUndeletedBeforeRevert");

    createFile(store, folderDeletedAfterRevert, System.currentTimeMillis(), null);

    fileDeletedBeforeRevert.delete();
    store.fileDelete(fileDeletedBeforeRevert, System.currentTimeMillis());

    fileUndeletedBeforeRevert.delete();
    store.fileDelete(fileUndeletedBeforeRevert, System.currentTimeMillis());
    createFile(
        store,
        fileUndeletedBeforeRevert,
        System.currentTimeMillis(),
        "fileUndeletedBeforeRevert BEFORE revert");

    // REVERT
    Thread.sleep(1000); // give me some time
    long revertToTS = System.currentTimeMillis();
    Thread.sleep(1000); // give me some time
    // REVERT

    lh.reset();
    changeFile(
        store, fileChangedAfterRevert, System.currentTimeMillis(), "fileChanged AFTER change");
    lh.waitUntilDone();

    fileDeletedAfterRevert.delete();
    store.fileDelete(fileDeletedAfterRevert, System.currentTimeMillis());

    createFile(
        store,
        fileDeletedBeforeRevert,
        System.currentTimeMillis(),
        "fileDeletedBeforeRevert after delete");

    createFile(store, fileCreatedAfterRevert, System.currentTimeMillis(), "fileCreatedAfterRevert");

    folderDeletedAfterRevert.delete();
    store.fileDelete(folderDeletedAfterRevert, System.currentTimeMillis());

    createFile(store, folderCreatedAfterRevert, System.currentTimeMillis(), null);

    // check datadir
    assertTrue(folder.exists());
    assertTrue(fileNotInStorage.exists());
    assertTrue(fileUnchanged.exists());
    assertTrue(fileChangedAfterRevert.exists());
    assertTrue(!fileDeletedAfterRevert.exists());
    assertTrue(fileDeletedBeforeRevert.exists());
    assertTrue(fileCreatedAfterRevert.exists());
    assertTrue(!folderDeletedAfterRevert.exists());
    assertTrue(folderCreatedAfterRevert.exists());

    File[] files = folder.listFiles();
    assertEquals(files.length, 7); //   fileNotInStorage
    //   fileUnchanged
    //   fileChangedAfterRevert
    // X fileDeletedAfterRevert
    //   fileDeletedBeforeRevert
    //   fileUndeletedBeforeRevert
    //   fileCreatedAfterRevert
    //   folderCreatedAfterRevert

    return revertToTS;
  }
  public void testSetLabel() throws Exception {
    LocalHistoryTestStore store = createStore();
    LogHandler lh = new LogHandler("copied file", LogHandler.Compare.STARTS_WITH);

    File folder = new File(dataDir, "datafolder");
    folder.mkdirs();

    // create the file
    File file1 = new File(folder, "file1");

    // lets create some history
    long ts = System.currentTimeMillis() - 4 * 24 * 60 * 60 * 1000;
    createFile(store, file1, ts + 1000, "data1");
    lh.reset();
    changeFile(store, file1, ts + 2000, "data1.1");
    lh.waitUntilDone();
    lh.reset();
    changeFile(store, file1, ts + 3000, "data1.2");
    lh.waitUntilDone();

    assertFile(file1, store, ts + 3000, -1, 3, 1, "data1.2", TOUCHED);

    String label = "My most beloved label";
    store.setLabel(file1, ts + 2000, label);

    assertFile(file1, store, ts + 3000, -1, 3, 1, "data1.2", TOUCHED, true);

    File labelsFile = store.getLabelsFile(file1);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    dos.writeLong(ts + 2000);
    dos.writeInt(label.length());
    dos.writeChars(label);
    dos.flush();

    assertDataInFile(labelsFile, baos.toByteArray());

    label = "My second most beloved label";
    store.setLabel(file1, ts + 1000, label);

    dos.writeLong(ts + 1000);
    dos.writeInt(label.length());
    dos.writeChars(label);
    dos.flush();

    labelsFile = store.getLabelsFile(file1);
    assertDataInFile(labelsFile, baos.toByteArray());

    store.setLabel(file1, ts + 2000, null);

    baos = new ByteArrayOutputStream();
    dos = new DataOutputStream(baos);
    dos.writeLong(ts + 1000);
    dos.writeInt(label.length());
    dos.writeChars(label);
    dos.flush();

    labelsFile = store.getLabelsFile(file1);
    assertDataInFile(labelsFile, baos.toByteArray());

    dos.close();
  }