@Test
  public void testCleanerDoesNotDeleteDirectoryWithLateAddedFiles() throws IOException {
    Stoppable stop = new StoppableImplementation();
    Configuration conf = UTIL.getConfiguration();
    final Path testDir = UTIL.getDataTestDir();
    final FileSystem fs = UTIL.getTestFileSystem();
    String confKey = "hbase.test.cleaner.delegates";
    conf.set(confKey, AlwaysDelete.class.getName());

    AllValidPaths chore =
      new AllValidPaths("test-file-cleaner", stop, conf, fs, testDir, confKey, POOL);
    // spy on the delegate to ensure that we don't check for directories
    AlwaysDelete delegate = (AlwaysDelete) chore.cleanersChain.get(0);
    AlwaysDelete spy = Mockito.spy(delegate);
    chore.cleanersChain.set(0, spy);

    // create the directory layout in the directory to clean
    final Path parent = new Path(testDir, "parent");
    Path file = new Path(parent, "someFile");
    fs.mkdirs(parent);
    // touch a new file
    fs.create(file).close();
    assertTrue("Test file didn't get created.", fs.exists(file));
    final Path addedFile = new Path(parent, "addedFile");

    // when we attempt to delete the original file, add another file in the same directory
    Mockito.doAnswer(new Answer<Boolean>() {
      @Override
      public Boolean answer(InvocationOnMock invocation) throws Throwable {
        fs.create(addedFile).close();
        CommonFSUtils.logFileSystemState(fs, testDir, LOG);
        return (Boolean) invocation.callRealMethod();
      }
    }).when(spy).isFileDeletable(Mockito.any());

    // run the chore
    chore.chore();

    // make sure all the directories + added file exist, but the original file is deleted
    assertTrue("Added file unexpectedly deleted", fs.exists(addedFile));
    assertTrue("Parent directory deleted unexpectedly", fs.exists(parent));
    assertFalse("Original file unexpectedly retained", fs.exists(file));
    Mockito.verify(spy, Mockito.times(1)).isFileDeletable(Mockito.any());
    Mockito.reset(spy);
  }
While cleaning a directory, all the files in the directory may be deleted, but there may be
another file added, in which case the directory shouldn't be deleted.
@throws IOException on failure
hbase-server/src/test/java/org/apache/hadoop/hbase/master/cleaner/TestCleanerChore.java