@Test
  public void testConfigError() {
    configureForMaxCleaning(5);
    final RepEnvInfo minfo = repEnvInfo[0];

    createGroup();
    populateDB(minfo.getEnv(), TEST_DB_NAME, 100);
    RepEnvInfo nrInfo = repEnvInfo[1];
    nrInfo.closeEnv();
    shiftVLSNRight(repEnvInfo[0].getEnv());
    try {
      setExceptionListener(nrInfo);
      nrInfo.openEnv();
      fail("exception expected");
    } catch (InsufficientLogException e) {
      NetworkRestore networkRestore = new NetworkRestore();

      final ReplicationConfig repConfig = repEnvInfo[0].getRepConfig();
      // bad node name
      repConfig.setNodeName("badname");
      ReplicationNode restoreNode = new RepNodeImpl(repConfig);
      final NetworkRestoreConfig config = new NetworkRestoreConfig();
      config.setLogProviders(Arrays.asList(restoreNode));
      try {
        networkRestore.execute(e, config);
        fail("exception expected");
      } catch (IllegalArgumentException iae) {
        // Expected
      }
    }
  }
  private void createRepEnvInfo(String sleepTime) throws Throwable {

    /*
     * Set a large buffer size and disable the checkpointing, so the
     * data in the buffer can only be flushed by the LogFlushTask.
     */
    EnvironmentConfig envConfig = RepTestUtils.createEnvConfig(Durability.COMMIT_NO_SYNC);
    envConfig.setConfigParam(EnvironmentParams.MAX_MEMORY.getName(), "20000000");
    envConfig.setConfigParam(EnvironmentParams.LOG_MEM_SIZE.getName(), "120000000");
    envConfig.setConfigParam(EnvironmentParams.NUM_LOG_BUFFERS.getName(), "4");
    envConfig.setConfigParam(EnvironmentConfig.ENV_RUN_CHECKPOINTER, "false");

    /* Configure the log flush task. */
    ReplicationConfig repConfig = new ReplicationConfig();
    repConfig.setConfigParam(ReplicationConfig.LOG_FLUSH_TASK_INTERVAL, sleepTime);
    repEnvInfo = RepTestUtils.setupEnvInfos(envRoot, 3, envConfig, repConfig);
  }
  private void openGroup() throws IOException {

    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);

    ReplicationConfig repConfig = new ReplicationConfig();
    repConfig.setConfigParam(RepParams.VLSN_LOG_CACHE_SIZE.getName(), "2");

    repEnvInfo = RepTestUtils.setupEnvInfos(envRoot, nNodes, envConfig, repConfig);
    master = RepTestUtils.joinGroup(repEnvInfo);

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(true);
    config.setTransactional(true);
    store = new EntityStore(master, "test", config);
    primaryIndex = store.getPrimaryIndex(Integer.class, AppData.class);
  }
  /*
   * Tests internal node removal APIs.
   */
  @Test
  public void testRemoveMember() {
    createGroup(groupSize);
    ReplicatedEnvironment master = repEnvInfo[0].getEnv();
    assertTrue(master.getState().isMaster());

    RepNode masterRep = repEnvInfo[0].getRepNode();

    /* Reduce the group size all the way down to one. */
    for (int i = 1; i < groupSize; i++) {
      assertTrue(!RepInternal.isClosed(repEnvInfo[i].getEnv()));
      masterRep.removeMember(repEnvInfo[i].getEnv().getNodeName());
      assertEquals((groupSize - i), masterRep.getGroup().getElectableGroupSize());
    }

    /* Close the replica handles*/
    for (int i = groupSize - 1; i > 0; i--) {
      repEnvInfo[i].closeEnv();
    }

    /* Attempting to re-open them with the same node names should fail. */
    for (int i = 1; i < groupSize; i++) {
      try {
        repEnvInfo[i].openEnv();
        fail("Exception expected");
      } catch (EnvironmentFailureException e) {
        /* Expected, the master should reject the attempt. */
        assertEquals(EnvironmentFailureReason.HANDSHAKE_ERROR, e.getReason());
      }
    }

    /* Doing the same but with different node names should be ok. */
    for (int i = 1; i < groupSize; i++) {
      final RepEnvInfo ri = repEnvInfo[i];
      final ReplicationConfig repConfig = ri.getRepConfig();
      TestUtils.removeLogFiles("RemoveRepEnvironments", ri.getEnvHome(), false);

      repConfig.setNodeName("ReplaceNode_" + i);
      ri.openEnv();
      assertEquals(i + 1, masterRep.getGroup().getElectableGroupSize());
    }
    master.close();
  }
  /** Test the basic configuration of LogFlusher. */
  @Test
  public void testBasicConfig() throws Throwable {

    try {
      EnvironmentConfig envConfig = RepTestUtils.createEnvConfig(Durability.COMMIT_NO_SYNC);
      ReplicationConfig repConfig = new ReplicationConfig();
      repConfig.setConfigParam(ReplicationMutableConfig.LOG_FLUSH_TASK_INTERVAL, "30 s");
      repEnvInfo = RepTestUtils.setupEnvInfos(envRoot, 3, envConfig, repConfig);
      RepTestUtils.joinGroup(repEnvInfo);
      assertTrue(repEnvInfo[0].isMaster());
      /* Check the LogFlusher configuration. */
      TimerTask[] oldTasks = new TimerTask[repEnvInfo.length];
      for (int i = 0; i < repEnvInfo.length; i++) {
        LogFlusher flusher = repEnvInfo[i].getRepNode().getLogFlusher();
        oldTasks[i] = flusher.getFlushTask();
        assertTrue(flusher != null);
        assertTrue(flusher.getFlushTask() != null);
        assertTrue(flusher.getFlushInterval() == 30000);
      }

      /* Check that those configuratins are mutable. */
      repConfig.setConfigParam(ReplicationMutableConfig.LOG_FLUSH_TASK_INTERVAL, "50 s");
      for (int i = 0; i < repEnvInfo.length; i++) {
        repEnvInfo[i].getEnv().setRepMutableConfig(repConfig);
      }

      for (int i = 0; i < repEnvInfo.length; i++) {
        LogFlusher flusher = repEnvInfo[i].getRepNode().getLogFlusher();
        assertTrue(flusher != null);
        assertTrue(flusher.getFlushTask() != null);
        assertTrue(flusher.getFlushTask() != oldTasks[i]);
        assertTrue(flusher.getFlushInterval() == 50000);
      }

      repConfig.setConfigParam(ReplicationMutableConfig.RUN_LOG_FLUSH_TASK, "false");
      for (int i = 0; i < repEnvInfo.length; i++) {
        repEnvInfo[i].getEnv().setRepMutableConfig(repConfig);
      }

      for (int i = 0; i < repEnvInfo.length; i++) {
        LogFlusher flusher = repEnvInfo[i].getRepNode().getLogFlusher();
        assertTrue(flusher != null);
        assertTrue(flusher.getFlushTask() == null);
      }

      RepTestUtils.shutdownRepEnvs(repEnvInfo);
      RepTestUtils.removeRepEnvironments(envRoot);

      repConfig.setConfigParam(ReplicationConfig.RUN_LOG_FLUSH_TASK, "false");
      repEnvInfo = RepTestUtils.setupEnvInfos(envRoot, 3, envConfig, repConfig);
      RepTestUtils.joinGroup(repEnvInfo);
      /* Check that the task is disabled. */
      for (int i = 0; i < repEnvInfo.length; i++) {
        assertTrue(repEnvInfo[i].getRepNode().getLogFlusher() == null);
      }
    } catch (Throwable t) {
      t.printStackTrace();
      throw t;
    } finally {
      RepTestUtils.shutdownRepEnvs(repEnvInfo);
    }
  }