@Test
public void testPreserveOnFileDownwardRecursion() throws IOException {

  FileSystem fs = FileSystem.get(config);
  EnumSet<FileAttribute> attributes = EnumSet.allOf(FileAttribute.class);
  // Remove ACL because tests run with dfs.namenode.acls.enabled false
  attributes.remove(FileAttribute.ACL);
  Path src = new Path("/tmp/src2");
  Path f0 = new Path("/f0");
  Path f1 = new Path("/d1/f1");
  Path f2 = new Path("/d1/d2/f2");
  Path d1 = new Path("/d1/");
  Path d2 = new Path("/d1/d2/");
  createFile(fs, src);
  createFile(fs, f0);
  createFile(fs, f1);
  createFile(fs, f2);
  fs.setPermission(src, almostFullPerm);
  fs.setOwner(src, "somebody", "somebody-group");
  fs.setTimes(src, 0, 0);
  fs.setReplication(src, (short) 1);
  fs.setPermission(d1, fullPerm);
  fs.setOwner(d1, "anybody", "anybody-group");
  fs.setTimes(d1, 400, 400);
  fs.setReplication(d1, (short) 3);
  fs.setPermission(d2, fullPerm);
  fs.setOwner(d2, "anybody", "anybody-group");
  fs.setTimes(d2, 300, 300);
  fs.setReplication(d2, (short) 3);
  fs.setPermission(f0, fullPerm);
  fs.setOwner(f0, "anybody", "anybody-group");
  fs.setTimes(f0, 200, 200);
  fs.setReplication(f0, (short) 3);
  fs.setPermission(f1, fullPerm);
  fs.setOwner(f1, "anybody", "anybody-group");
  fs.setTimes(f1, 200, 200);
  fs.setReplication(f1, (short) 3);
  fs.setPermission(f2, fullPerm);
  fs.setOwner(f2, "anybody", "anybody-group");
  fs.setTimes(f2, 200, 200);
  fs.setReplication(f2, (short) 3);
  CopyListingFileStatus srcStatus = new CopyListingFileStatus(fs.getFileStatus(src));
  DistCpUtils.preserve(fs, f0, srcStatus, attributes, false);
  cluster.triggerHeartbeats();
  // FileStatus.equals only compares path field, must explicitly compare all fields
  // attributes of src -> f0 ? should be yes
  assertStatusEqual(fs, f0, srcStatus);
  // attributes of src -> f1 ? should be no
  CopyListingFileStatus f1Status = new CopyListingFileStatus(fs.getFileStatus(f1));
  Assert.assertFalse(srcStatus.getPermission().equals(f1Status.getPermission()));
  Assert.assertFalse(srcStatus.getOwner().equals(f1Status.getOwner()));
  Assert.assertFalse(srcStatus.getGroup().equals(f1Status.getGroup()));
  Assert.assertFalse(srcStatus.getAccessTime() == f1Status.getAccessTime());
  Assert.assertFalse(srcStatus.getModificationTime() == f1Status.getModificationTime());
  Assert.assertFalse(srcStatus.getReplication() == f1Status.getReplication());
  // attributes of src -> f2 ? should be no
  CopyListingFileStatus f2Status = new CopyListingFileStatus(fs.getFileStatus(f2));
  Assert.assertFalse(srcStatus.getPermission().equals(f2Status.getPermission()));
  Assert.assertFalse(srcStatus.getOwner().equals(f2Status.getOwner()));
  Assert.assertFalse(srcStatus.getGroup().equals(f2Status.getGroup()));
  Assert.assertFalse(srcStatus.getAccessTime() == f2Status.getAccessTime());
  Assert.assertFalse(srcStatus.getModificationTime() == f2Status.getModificationTime());
  Assert.assertFalse(srcStatus.getReplication() == f2Status.getReplication());
  // attributes of src -> d1 ? should be no
  CopyListingFileStatus d1Status = new CopyListingFileStatus(fs.getFileStatus(d1));
  Assert.assertFalse(srcStatus.getPermission().equals(d1Status.getPermission()));
  Assert.assertFalse(srcStatus.getOwner().equals(d1Status.getOwner()));
  Assert.assertFalse(srcStatus.getGroup().equals(d1Status.getGroup()));
  Assert.assertTrue(d1Status.getAccessTime() == 400);
  Assert.assertTrue(d1Status.getModificationTime() == 400);
  Assert.assertFalse(srcStatus.getReplication() == d1Status.getReplication());
  // attributes of src -> d2 ? should be no
  CopyListingFileStatus d2Status = new CopyListingFileStatus(fs.getFileStatus(d2));
  Assert.assertFalse(srcStatus.getPermission().equals(d2Status.getPermission()));
  Assert.assertFalse(srcStatus.getOwner().equals(d2Status.getOwner()));
  Assert.assertFalse(srcStatus.getGroup().equals(d2Status.getGroup()));
  Assert.assertTrue(d2Status.getAccessTime() == 300);
  Assert.assertTrue(d2Status.getModificationTime() == 300);
  Assert.assertFalse(srcStatus.getReplication() == d2Status.getReplication());
}