@Test
  public void testIndexRebuilds() throws Exception {
    IOHelper.deleteFile(schedulerStoreDir);

    JobSchedulerStoreImpl schedulerStore = createScheduler();
    broker = createBroker(schedulerStore);
    broker.start();
    ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
    Connection connection = cf.createConnection();
    connection.start();
    for (int i = 0; i < NUM_JOBS; ++i) {
      scheduleRepeating(connection);
    }
    connection.close();

    JobScheduler scheduler = schedulerStore.getJobScheduler("JMS");
    assertNotNull(scheduler);
    assertEquals(NUM_JOBS, scheduler.getAllJobs().size());

    broker.stop();

    IOHelper.delete(new File(schedulerStoreDir, "scheduleDB.data"));

    schedulerStore = createScheduler();
    broker = createBroker(schedulerStore);
    broker.start();

    scheduler = schedulerStore.getJobScheduler("JMS");
    assertNotNull(scheduler);
    assertEquals(NUM_JOBS, scheduler.getAllJobs().size());
  }
  protected synchronized void intialize() throws Exception {
    if (isStarted()) {
      if (this.initialized == false) {
        if (this.directory == null) {
          this.directory =
              new File(IOHelper.getDefaultDataDirectory() + File.pathSeparator + "delayedDB");
        }
        IOHelper.mkdirs(this.directory);
        lock();
        this.journal = new Journal();
        this.journal.setDirectory(directory);
        this.journal.setMaxFileLength(getJournalMaxFileLength());
        this.journal.setWriteBatchSize(getJournalMaxWriteBatchSize());
        this.journal.start();
        this.pageFile = new PageFile(directory, "tmpDB");
        this.pageFile.setEnablePageCaching(getIndexEnablePageCaching());
        this.pageFile.setPageSize(getIndexPageSize());
        this.pageFile.setWriteBatchSize(getIndexWriteBatchSize());
        this.pageFile.setPageCacheSize(getIndexCacheSize());
        this.pageFile.load();

        this.pageFile
            .tx()
            .execute(
                new Transaction.Closure<IOException>() {
                  public void execute(Transaction tx) throws IOException {
                    if (pageFile.getPageCount() == 0) {
                      Page<MetaData> page = tx.allocate();
                      assert page.getPageId() == 0;
                      page.set(metaData);
                      metaData.page = page;
                      metaData.createIndexes(tx);
                      tx.store(metaData.page, metaDataMarshaller, true);

                    } else {
                      Page<MetaData> page = tx.load(0, metaDataMarshaller);
                      metaData = page.get();
                      metaData.page = page;
                    }
                    metaData.load(tx);
                    metaData.loadLists(tx, persistentLists);
                  }
                });
        this.pageFile.flush();

        if (cleanupInterval > 0) {
          if (scheduler == null) {
            scheduler = new Scheduler(PListStoreImpl.class.getSimpleName());
            scheduler.start();
          }
          scheduler.executePeriodically(this, cleanupInterval);
        }
        this.initialized = true;
        LOG.info(this + " initialized");
      }
    }
  }
  @Test
  public void testDeleteOnUnlockIfLocked() throws Exception {

    File lockFile = new File(IOHelper.getDefaultDataDirectory(), "lockToTest2");
    IOHelper.mkdirs(lockFile.getParentFile());
    lockFile.createNewFile();

    LockFile underTest = new LockFile(lockFile, true);

    underTest.lock();

    assertTrue("valid", underTest.keepAlive());

    underTest.unlock();

    assertFalse("file deleted on unlock", lockFile.exists());
  }
  @Test
  public void testIndexRebuildsAfterSomeJobsExpire() throws Exception {
    IOHelper.deleteFile(schedulerStoreDir);

    JobSchedulerStoreImpl schedulerStore = createScheduler();
    broker = createBroker(schedulerStore);
    broker.start();
    ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
    Connection connection = cf.createConnection();
    connection.start();
    for (int i = 0; i < NUM_JOBS; ++i) {
      scheduleRepeating(connection);
      scheduleOneShot(connection);
    }
    connection.close();

    JobScheduler scheduler = schedulerStore.getJobScheduler("JMS");
    assertNotNull(scheduler);
    assertEquals(NUM_JOBS * 2, scheduler.getAllJobs().size());

    final JobScheduler awaitingOneShotTimeout = scheduler;
    assertTrue(
        "One shot jobs should time out",
        Wait.waitFor(
            new Wait.Condition() {

              @Override
              public boolean isSatisified() throws Exception {
                return awaitingOneShotTimeout.getAllJobs().size() == NUM_JOBS;
              }
            },
            TimeUnit.MINUTES.toMillis(2)));

    broker.stop();

    IOHelper.delete(new File(schedulerStoreDir, "scheduleDB.data"));

    schedulerStore = createScheduler();
    broker = createBroker(schedulerStore);
    broker.start();

    scheduler = schedulerStore.getJobScheduler("JMS");
    assertNotNull(scheduler);
    assertEquals(NUM_JOBS, scheduler.getAllJobs().size());
  }
  @Test
  public void testNoDeleteOnUnlockIfNotLocked() throws Exception {

    File lockFile = new File(IOHelper.getDefaultDataDirectory(), "lockToTest1");
    IOHelper.mkdirs(lockFile.getParentFile());
    lockFile.createNewFile();

    LockFile underTest = new LockFile(lockFile, true);

    underTest.lock();

    lockFile.delete();

    assertFalse("no longer valid", underTest.keepAlive());

    // a slave gets in
    lockFile.createNewFile();

    underTest.unlock();

    assertTrue("file still exists after unlock when not locked", lockFile.exists());
  }