Modified: hadoop/common/branches/HDFS-4685/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeAcl.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-4685/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeAcl.java?rev=1559267&r1=1559266&r2=1559267&view=diff ============================================================================== --- hadoop/common/branches/HDFS-4685/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeAcl.java (original) +++ hadoop/common/branches/HDFS-4685/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeAcl.java Fri Jan 17 22:05:47 2014 @@ -17,54 +17,786 @@ */ package org.apache.hadoop.hdfs.server.namenode; +import static org.apache.hadoop.hdfs.server.namenode.AclTestHelpers.*; +import static org.apache.hadoop.fs.permission.AclEntryScope.*; +import static org.apache.hadoop.fs.permission.AclEntryType.*; +import static org.apache.hadoop.fs.permission.FsAction.*; +import static org.junit.Assert.*; + +import java.io.FileNotFoundException; import java.io.IOException; +import java.util.List; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.permission.AclEntry; -import org.apache.hadoop.fs.permission.AclEntryScope; -import org.apache.hadoop.fs.permission.AclEntryType; import org.apache.hadoop.fs.permission.AclStatus; -import org.apache.hadoop.fs.permission.FsAction; +import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.hdfs.MiniDFSCluster; +import org.apache.hadoop.hdfs.protocol.AclException; +import org.apache.hadoop.io.IOUtils; import org.junit.AfterClass; -import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.google.common.collect.Lists; +/** + * Tests NameNode interaction for all ACL modification APIs. This test suite + * also covers interaction of setPermission with inodes that have ACLs. + */ public class TestNameNodeAcl { private static MiniDFSCluster cluster; private static Configuration conf; + private static FileSystem fs; + private static int pathCount = 0; + private static Path path; @BeforeClass - public static void setUp() throws Exception { + public static void init() throws Exception { conf = new Configuration(); cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build(); cluster.waitActive(); + fs = cluster.getFileSystem(); } @AfterClass - public static void tearDown() throws Exception { - cluster.shutdown(); + public static void shutdown() throws Exception { + IOUtils.cleanup(null, fs); + if (cluster != null) { + cluster.shutdown(); + } + } + + @Before + public void setUp() { + pathCount += 1; + path = new Path("/p" + pathCount); + } + + @Test + public void testModifyAclEntries() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo", READ_EXECUTE), + aclEntry(DEFAULT, USER, "foo", READ_EXECUTE)); + fs.modifyAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", READ_EXECUTE), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", READ_EXECUTE), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testModifyAclEntriesOnlyAccess() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo", READ_EXECUTE)); + fs.modifyAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", READ_EXECUTE), + aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testModifyAclEntriesOnlyDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, "foo", READ_EXECUTE)); + fs.modifyAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", READ_EXECUTE), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testModifyAclEntriesMinimal() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo", READ_WRITE)); + fs.modifyAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", READ_WRITE), + aclEntry(ACCESS, GROUP, READ) }, returned); + assertPermission((short)02660); + assertAclFeature(true); + } + + @Test + public void testModifyAclEntriesMinimalDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE)); + fs.modifyAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testModifyAclEntriesCustomMask() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, MASK, NONE)); + fs.modifyAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ) }, returned); + assertPermission((short)02600); + assertAclFeature(true); + } + + @Test + public void testModifyAclEntriesStickyBit() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)01750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo", READ_EXECUTE), + aclEntry(DEFAULT, USER, "foo", READ_EXECUTE)); + fs.modifyAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", READ_EXECUTE), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", READ_EXECUTE), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)03750); + assertAclFeature(true); + } + + @Test(expected=FileNotFoundException.class) + public void testModifyAclEntriesPathNotFound() throws IOException { + // Path has not been created. + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE)); + fs.modifyAclEntries(path, aclSpec); + } + + @Test(expected=AclException.class) + public void testModifyAclEntriesDefaultOnFile() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.modifyAclEntries(path, aclSpec); + } + + @Test + public void testRemoveAclEntries() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo"), + aclEntry(DEFAULT, USER, "foo")); + fs.removeAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testRemoveAclEntriesOnlyAccess() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, USER, "bar", READ_WRITE), + aclEntry(ACCESS, GROUP, READ_WRITE), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo")); + fs.removeAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "bar", READ_WRITE), + aclEntry(ACCESS, GROUP, READ_WRITE) }, returned); + assertPermission((short)02760); + assertAclFeature(true); + } + + @Test + public void testRemoveAclEntriesOnlyDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL), + aclEntry(DEFAULT, USER, "bar", READ_EXECUTE)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, "foo")); + fs.removeAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "bar", READ_EXECUTE), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testRemoveAclEntriesMinimal() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0760)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_WRITE), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo"), + aclEntry(ACCESS, MASK)); + fs.removeAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { }, returned); + assertPermission((short)0760); + assertAclFeature(false); + } + + + @Test + public void testRemoveAclEntriesMinimalDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo"), + aclEntry(ACCESS, MASK), + aclEntry(DEFAULT, USER, "foo"), + aclEntry(DEFAULT, MASK)); + fs.removeAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testRemoveAclEntriesStickyBit() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)01750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo"), + aclEntry(DEFAULT, USER, "foo")); + fs.removeAclEntries(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)03750); + assertAclFeature(true); + } + + @Test(expected=FileNotFoundException.class) + public void testRemoveAclEntriesPathNotFound() throws IOException { + // Path has not been created. + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, "foo")); + fs.removeAclEntries(path, aclSpec); + } + + @Test + public void testRemoveDefaultAcl() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + fs.removeDefaultAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); + assertPermission((short)02770); + assertAclFeature(true); + } + + @Test + public void testRemoveDefaultAclOnlyAccess() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + fs.removeDefaultAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); + assertPermission((short)02770); + assertAclFeature(true); + } + + @Test + public void testRemoveDefaultAclOnlyDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + fs.removeDefaultAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { }, returned); + assertPermission((short)0750); + assertAclFeature(false); + } + + @Test + public void testRemoveDefaultAclMinimal() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + fs.removeDefaultAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { }, returned); + assertPermission((short)0750); + assertAclFeature(false); + } + + @Test + public void testRemoveDefaultAclStickyBit() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)01750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + fs.removeDefaultAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); + assertPermission((short)03770); + assertAclFeature(true); + } + + @Test(expected=FileNotFoundException.class) + public void testRemoveDefaultAclPathNotFound() throws IOException { + // Path has not been created. + fs.removeDefaultAcl(path); + } + + @Test + public void testRemoveAcl() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + fs.removeAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { }, returned); + assertPermission((short)0750); + assertAclFeature(false); + } + + @Test + public void testRemoveAclMinimalAcl() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + fs.removeAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { }, returned); + assertPermission((short)0640); + assertAclFeature(false); + } + + @Test + public void testRemoveAclStickyBit() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)01750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + fs.removeAcl(path); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { }, returned); + assertPermission((short)01750); + assertAclFeature(false); + } + + @Test(expected=FileNotFoundException.class) + public void testRemoveAclPathNotFound() throws IOException { + // Path has not been created. + fs.removeAcl(path); } @Test public void testSetAcl() throws IOException { - Path p = new Path("/p"); - FileSystem fs = cluster.getFileSystem(); - fs.create(p).close(); - AclEntry e = new AclEntry.Builder().setName("foo") - .setPermission(FsAction.READ_EXECUTE).setScope(AclEntryScope.DEFAULT) - .setType(AclEntryType.OTHER).build(); - fs.setAcl(p, Lists.newArrayList(e)); - AclStatus s = fs.getAclStatus(p); - AclEntry[] returned = Lists.newArrayList(s.getEntries()).toArray( - new AclEntry[0]); - Assert.assertArrayEquals(new AclEntry[] { e }, returned); + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, ALL), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02770); + assertAclFeature(true); + } + + @Test + public void testSetAclOnlyAccess() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, READ_WRITE), + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ) }, returned); + assertPermission((short)02640); + assertAclFeature(true); + } + + @Test + public void testSetAclOnlyDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, ALL), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testSetAclMinimal() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0644)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, READ_WRITE), + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, READ_WRITE), + aclEntry(ACCESS, GROUP, READ), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { }, returned); + assertPermission((short)0640); + assertAclFeature(false); + } + + @Test + public void testSetAclMinimalDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE)); + fs.setAcl(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02750); + assertAclFeature(true); + } + + @Test + public void testSetAclCustomMask() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, READ_WRITE), + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ), + aclEntry(ACCESS, MASK, ALL), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ) }, returned); + assertPermission((short)02670); + assertAclFeature(true); + } + + @Test + public void testSetAclStickyBit() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)01750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, ALL), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)03770); + assertAclFeature(true); + } + + @Test(expected=FileNotFoundException.class) + public void testSetAclPathNotFound() throws IOException { + // Path has not been created. + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, READ_WRITE), + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + } + + @Test(expected=AclException.class) + public void testSetAclDefaultOnFile() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + } + + @Test + public void testSetPermission() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + fs.setPermission(path, FsPermission.createImmutable((short)0700)); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, ALL), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02700); + assertAclFeature(true); + } + + @Test + public void testSetPermissionOnlyAccess() throws IOException { + FileSystem.create(fs, path, FsPermission.createImmutable((short)0640)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, READ_WRITE), + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ), + aclEntry(ACCESS, OTHER, NONE)); + fs.setAcl(path, aclSpec); + fs.setPermission(path, FsPermission.createImmutable((short)0600)); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(ACCESS, USER, "foo", READ), + aclEntry(ACCESS, GROUP, READ) }, returned); + assertPermission((short)02600); + assertAclFeature(true); + } + + @Test + public void testSetPermissionOnlyDefault() throws IOException { + FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); + List<AclEntry> aclSpec = Lists.newArrayList( + aclEntry(ACCESS, USER, ALL), + aclEntry(ACCESS, GROUP, READ_EXECUTE), + aclEntry(ACCESS, OTHER, NONE), + aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + fs.setPermission(path, FsPermission.createImmutable((short)0700)); + AclStatus s = fs.getAclStatus(path); + AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); + assertArrayEquals(new AclEntry[] { + aclEntry(DEFAULT, USER, ALL), + aclEntry(DEFAULT, USER, "foo", ALL), + aclEntry(DEFAULT, GROUP, READ_EXECUTE), + aclEntry(DEFAULT, MASK, ALL), + aclEntry(DEFAULT, OTHER, NONE) }, returned); + assertPermission((short)02700); + assertAclFeature(true); + } + + /** + * Asserts whether or not the inode for the test path has an AclFeature. + * + * @param expectAclFeature boolean true if an AclFeature must be present, + * false if an AclFeature must not be present + * @throws IOException thrown if there is an I/O error + */ + private static void assertAclFeature(boolean expectAclFeature) + throws IOException { + INode inode = cluster.getNamesystem().getFSDirectory().getRoot() + .getNode(path.toUri().getPath(), false); + assertNotNull(inode); + assertTrue(inode instanceof INodeWithAdditionalFields); + AclFeature aclFeature = ((INodeWithAdditionalFields)inode).getAclFeature(); + if (expectAclFeature) { + assertNotNull(aclFeature); + } else { + assertNull(aclFeature); + } + } + + /** + * Asserts the value of the FsPermission bits on the inode of the test path. + * + * @param perm short expected permission bits + * @throws IOException thrown if there is an I/O error + */ + private static void assertPermission(short perm) throws IOException { + assertEquals(FsPermission.createImmutable(perm), + fs.getFileStatus(path).getPermission()); } }