private void durabilityTest(String method, Durability tableDurability,
    Durability mutationDurability, long timeout, boolean expectAppend, final boolean expectSync,
    final boolean expectSyncFromLogSyncer) throws Exception {
    Configuration conf = HBaseConfiguration.create(CONF);
    conf.setLong(AbstractFSWAL.WAL_SHUTDOWN_WAIT_TIMEOUT_MS, 60 * 60 * 1000);
    method = method + "_" + tableDurability.name() + "_" + mutationDurability.name();
    byte[] family = Bytes.toBytes("family");
    Path logDir = new Path(new Path(dir + method), "log");
    final Configuration walConf = new Configuration(conf);
    CommonFSUtils.setRootDir(walConf, logDir);
    // XXX: The spied AsyncFSWAL can not work properly because of a Mockito defect that can not
    // deal with classes which have a field of an inner class. See discussions in HBASE-15536.
    walConf.set(WALFactory.WAL_PROVIDER, "filesystem");
    final WALFactory wals = new WALFactory(walConf, HBaseTestingUtil.getRandomUUID().toString());
    final WAL wal = spy(wals.getWAL(RegionInfoBuilder.newBuilder(tableName).build()));
    this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,
      false, tableDurability, wal, new byte[][] { family });

    Put put = new Put(Bytes.toBytes("r1"));
    put.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("v1"));
    put.setDurability(mutationDurability);
    region.put(put);

    // verify append called or not
    verify(wal, expectAppend ? times(1) : never()).appendData((RegionInfo) any(),
      (WALKeyImpl) any(), (WALEdit) any());

    // verify sync called or not
    if (expectSync || expectSyncFromLogSyncer) {
      TEST_UTIL.waitFor(timeout, new Waiter.Predicate<Exception>() {
        @Override
        public boolean evaluate() throws Exception {
          try {
            if (expectSync) {
              verify(wal, times(1)).sync(anyLong()); // Hregion calls this one
            } else if (expectSyncFromLogSyncer) {
              verify(wal, times(1)).sync(); // wal syncer calls this one
            }
          } catch (Throwable ignore) {
          }
          return true;
        }
      });
    } else {
      // verify(wal, never()).sync(anyLong());
      verify(wal, never()).sync();
    }

    HBaseTestingUtil.closeRegionAndWAL(this.region);
    wals.close();
    this.region = null;
  }
For this test,the spied {@link AsyncFSWAL} can not work properly because of a Mockito defect
that can not deal with classes which have a field of an inner class. See discussions in
HBASE-15536.When we reuse the code of {@link AsyncFSWAL} for {@link FSHLog}, this test could
not work for {@link FSHLog} also.
hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java