@Test
  public void testRemoveAclExceedsQuota() throws Exception {
    Path filePath = new Path(path, "file1");
    Path fileSnapshotPath = new Path(snapshotPath, "file1");
    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0755));
    hdfs.allowSnapshot(path);
    hdfs.setQuota(path, 3, HdfsConstants.QUOTA_DONT_SET);
    FileSystem.create(hdfs, filePath, FsPermission.createImmutable((short) 0600)).close();
    hdfs.setPermission(filePath, FsPermission.createImmutable((short) 0600));
    List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, "bruce", READ_WRITE));
    hdfs.modifyAclEntries(filePath, aclSpec);

    hdfs.createSnapshot(path, snapshotName);

    AclStatus s = hdfs.getAclStatus(filePath);
    AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {aclEntry(ACCESS, USER, "bruce", READ_WRITE), aclEntry(ACCESS, GROUP, NONE)},
        returned);
    assertPermission((short) 010660, filePath);

    s = hdfs.getAclStatus(fileSnapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {aclEntry(ACCESS, USER, "bruce", READ_WRITE), aclEntry(ACCESS, GROUP, NONE)},
        returned);
    assertPermission((short) 010660, filePath);

    aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, "bruce", READ));
    hdfs.removeAcl(filePath);
  }
  private static void doSnapshotRootChangeAssertions(Path path, Path snapshotPath)
      throws Exception {
    AclStatus s = hdfs.getAclStatus(path);
    AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {
          aclEntry(ACCESS, USER, "diana", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE)
        },
        returned);
    assertPermission((short) 010550, path);

    s = hdfs.getAclStatus(snapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {
          aclEntry(ACCESS, USER, "bruce", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE)
        },
        returned);
    assertPermission((short) 010750, snapshotPath);

    assertDirPermissionDenied(fsAsBruce, BRUCE, path);
    assertDirPermissionGranted(fsAsDiana, DIANA, path);
    assertDirPermissionGranted(fsAsBruce, BRUCE, snapshotPath);
    assertDirPermissionDenied(fsAsDiana, DIANA, snapshotPath);
  }
  @Test
  public void testOriginalAclEnforcedForSnapshotRootAfterChange() throws Exception {
    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0700));
    List<AclEntry> aclSpec =
        Lists.newArrayList(
            aclEntry(ACCESS, USER, ALL),
            aclEntry(ACCESS, USER, "bruce", READ_EXECUTE),
            aclEntry(ACCESS, GROUP, NONE),
            aclEntry(ACCESS, OTHER, NONE));
    hdfs.setAcl(path, aclSpec);

    assertDirPermissionGranted(fsAsBruce, BRUCE, path);
    assertDirPermissionDenied(fsAsDiana, DIANA, path);

    SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);

    // Both original and snapshot still have same ACL.
    AclStatus s = hdfs.getAclStatus(path);
    AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {
          aclEntry(ACCESS, USER, "bruce", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE)
        },
        returned);
    assertPermission((short) 010750, path);

    s = hdfs.getAclStatus(snapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {
          aclEntry(ACCESS, USER, "bruce", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE)
        },
        returned);
    assertPermission((short) 010750, snapshotPath);

    assertDirPermissionGranted(fsAsBruce, BRUCE, snapshotPath);
    assertDirPermissionDenied(fsAsDiana, DIANA, snapshotPath);

    aclSpec =
        Lists.newArrayList(
            aclEntry(ACCESS, USER, READ_EXECUTE),
            aclEntry(ACCESS, USER, "diana", READ_EXECUTE),
            aclEntry(ACCESS, GROUP, NONE),
            aclEntry(ACCESS, OTHER, NONE));
    hdfs.setAcl(path, aclSpec);

    // Original has changed, but snapshot still has old ACL.
    doSnapshotRootChangeAssertions(path, snapshotPath);
    restart(false);
    doSnapshotRootChangeAssertions(path, snapshotPath);
    restart(true);
    doSnapshotRootChangeAssertions(path, snapshotPath);
  }
  @Test
  public void testModifyReadsCurrentState() throws Exception {
    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0700));

    SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);

    List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, "bruce", ALL));
    hdfs.modifyAclEntries(path, aclSpec);

    aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, "diana", READ_EXECUTE));
    hdfs.modifyAclEntries(path, aclSpec);

    AclEntry[] expected =
        new AclEntry[] {
          aclEntry(ACCESS, USER, "bruce", ALL),
          aclEntry(ACCESS, USER, "diana", READ_EXECUTE),
          aclEntry(ACCESS, GROUP, NONE)
        };
    AclStatus s = hdfs.getAclStatus(path);
    AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010770, path);
    assertDirPermissionGranted(fsAsBruce, BRUCE, path);
    assertDirPermissionGranted(fsAsDiana, DIANA, path);
  }
 @Test
 public void testGetAclStatusDotSnapshotPath() throws Exception {
   hdfs.mkdirs(path);
   SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);
   AclStatus s = hdfs.getAclStatus(new Path(path, ".snapshot"));
   AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
   assertArrayEquals(new AclEntry[] {}, returned);
 }
  private static void doSnapshotContentsChangeAssertions(
      Path filePath, Path fileSnapshotPath, Path subdirPath, Path subdirSnapshotPath)
      throws Exception {
    AclEntry[] expected =
        new AclEntry[] {aclEntry(ACCESS, USER, "diana", ALL), aclEntry(ACCESS, GROUP, NONE)};
    AclStatus s = hdfs.getAclStatus(filePath);
    AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010570, filePath);
    assertFilePermissionDenied(fsAsBruce, BRUCE, filePath);
    assertFilePermissionGranted(fsAsDiana, DIANA, filePath);

    s = hdfs.getAclStatus(subdirPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010570, subdirPath);
    assertDirPermissionDenied(fsAsBruce, BRUCE, subdirPath);
    assertDirPermissionGranted(fsAsDiana, DIANA, subdirPath);

    expected =
        new AclEntry[] {
          aclEntry(ACCESS, USER, "bruce", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE)
        };
    s = hdfs.getAclStatus(fileSnapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010550, fileSnapshotPath);
    assertFilePermissionGranted(fsAsBruce, BRUCE, fileSnapshotPath);
    assertFilePermissionDenied(fsAsDiana, DIANA, fileSnapshotPath);

    s = hdfs.getAclStatus(subdirSnapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010550, subdirSnapshotPath);
    assertDirPermissionGranted(fsAsBruce, BRUCE, subdirSnapshotPath);
    assertDirPermissionDenied(fsAsDiana, DIANA, subdirSnapshotPath);
  }
  @Test
  public void testDefaultAclNotCopiedToAccessAclOfNewSnapshot() throws Exception {
    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0700));
    List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(DEFAULT, USER, "bruce", READ_EXECUTE));
    hdfs.modifyAclEntries(path, aclSpec);

    SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);

    AclStatus s = hdfs.getAclStatus(path);
    AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {
          aclEntry(DEFAULT, USER, ALL),
          aclEntry(DEFAULT, USER, "bruce", READ_EXECUTE),
          aclEntry(DEFAULT, GROUP, NONE),
          aclEntry(DEFAULT, MASK, READ_EXECUTE),
          aclEntry(DEFAULT, OTHER, NONE)
        },
        returned);
    assertPermission((short) 010700, path);

    s = hdfs.getAclStatus(snapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(
        new AclEntry[] {
          aclEntry(DEFAULT, USER, ALL),
          aclEntry(DEFAULT, USER, "bruce", READ_EXECUTE),
          aclEntry(DEFAULT, GROUP, NONE),
          aclEntry(DEFAULT, MASK, READ_EXECUTE),
          aclEntry(DEFAULT, OTHER, NONE)
        },
        returned);
    assertPermission((short) 010700, snapshotPath);

    assertDirPermissionDenied(fsAsBruce, BRUCE, snapshotPath);
  }
  @Test
  public void testOriginalAclEnforcedForSnapshotContentsAfterRemoval() throws Exception {
    Path filePath = new Path(path, "file1");
    Path subdirPath = new Path(path, "subdir1");
    Path fileSnapshotPath = new Path(snapshotPath, "file1");
    Path subdirSnapshotPath = new Path(snapshotPath, "subdir1");
    FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0777));
    FileSystem.create(hdfs, filePath, FsPermission.createImmutable((short) 0600)).close();
    FileSystem.mkdirs(hdfs, subdirPath, FsPermission.createImmutable((short) 0700));
    List<AclEntry> aclSpec =
        Lists.newArrayList(
            aclEntry(ACCESS, USER, READ_EXECUTE),
            aclEntry(ACCESS, USER, "bruce", READ_EXECUTE),
            aclEntry(ACCESS, GROUP, NONE),
            aclEntry(ACCESS, OTHER, NONE));
    hdfs.setAcl(filePath, aclSpec);
    hdfs.setAcl(subdirPath, aclSpec);

    assertFilePermissionGranted(fsAsBruce, BRUCE, filePath);
    assertFilePermissionDenied(fsAsDiana, DIANA, filePath);
    assertDirPermissionGranted(fsAsBruce, BRUCE, subdirPath);
    assertDirPermissionDenied(fsAsDiana, DIANA, subdirPath);

    SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);

    // Both original and snapshot still have same ACL.
    AclEntry[] expected =
        new AclEntry[] {
          aclEntry(ACCESS, USER, "bruce", READ_EXECUTE), aclEntry(ACCESS, GROUP, NONE)
        };
    AclStatus s = hdfs.getAclStatus(filePath);
    AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010550, filePath);

    s = hdfs.getAclStatus(subdirPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010550, subdirPath);

    s = hdfs.getAclStatus(fileSnapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010550, fileSnapshotPath);
    assertFilePermissionGranted(fsAsBruce, BRUCE, fileSnapshotPath);
    assertFilePermissionDenied(fsAsDiana, DIANA, fileSnapshotPath);

    s = hdfs.getAclStatus(subdirSnapshotPath);
    returned = s.getEntries().toArray(new AclEntry[0]);
    assertArrayEquals(expected, returned);
    assertPermission((short) 010550, subdirSnapshotPath);
    assertDirPermissionGranted(fsAsBruce, BRUCE, subdirSnapshotPath);
    assertDirPermissionDenied(fsAsDiana, DIANA, subdirSnapshotPath);

    hdfs.removeAcl(filePath);
    hdfs.removeAcl(subdirPath);

    // Original has changed, but snapshot still has old ACL.
    doSnapshotContentsRemovalAssertions(filePath, fileSnapshotPath, subdirPath, subdirSnapshotPath);
    restart(false);
    doSnapshotContentsRemovalAssertions(filePath, fileSnapshotPath, subdirPath, subdirSnapshotPath);
    restart(true);
    doSnapshotContentsRemovalAssertions(filePath, fileSnapshotPath, subdirPath, subdirSnapshotPath);
  }