| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| 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.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.CommonConfigurationKeys; |
| 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.AclStatus; |
| import org.apache.hadoop.fs.permission.FsPermission; |
| import org.apache.hadoop.fs.permission.FsAction; |
| import org.apache.hadoop.hdfs.DFSConfigKeys; |
| import org.apache.hadoop.hdfs.DFSTestUtil; |
| import org.apache.hadoop.hdfs.MiniDFSCluster; |
| import org.apache.hadoop.hdfs.protocol.AclException; |
| import org.apache.hadoop.hdfs.protocol.FsPermissionExtension; |
| import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction; |
| import org.apache.hadoop.hdfs.server.namenode.FSDirectory.DirOp; |
| import org.apache.hadoop.io.IOUtils; |
| import org.apache.hadoop.security.AccessControlException; |
| import org.apache.hadoop.security.UserGroupInformation; |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.ExpectedException; |
| |
| import com.google.common.collect.ImmutableList; |
| 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 abstract class FSAclBaseTest { |
| private static final UserGroupInformation BRUCE = |
| UserGroupInformation.createUserForTesting("bruce", new String[] { }); |
| private static final UserGroupInformation DIANA = |
| UserGroupInformation.createUserForTesting("diana", new String[] { }); |
| private static final UserGroupInformation SUPERGROUP_MEMBER = |
| UserGroupInformation.createUserForTesting("super", new String[] { |
| DFSConfigKeys.DFS_PERMISSIONS_SUPERUSERGROUP_DEFAULT }); |
| // group member |
| private static final UserGroupInformation BOB = UserGroupInformation |
| .createUserForTesting("bob", new String[] { "groupY", "groupZ" }); |
| |
| protected static MiniDFSCluster cluster; |
| protected static Configuration conf; |
| private static int pathCount = 0; |
| private static Path path; |
| |
| @Rule |
| public ExpectedException exception = ExpectedException.none(); |
| |
| private FileSystem fs, fsAsBruce, fsAsDiana, fsAsSupergroupMember, fsAsBob; |
| |
| protected static void startCluster() throws IOException { |
| conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, true); |
| cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build(); |
| cluster.waitActive(); |
| } |
| |
| @AfterClass |
| public static void shutdown() { |
| if (cluster != null) { |
| cluster.shutdown(); |
| } |
| } |
| |
| @Before |
| public void setUp() throws Exception { |
| pathCount += 1; |
| path = new Path("/p" + pathCount); |
| initFileSystems(); |
| } |
| |
| @After |
| public void destroyFileSystems() { |
| IOUtils.cleanup(null, fs, fsAsBruce, fsAsDiana, fsAsSupergroupMember); |
| fs = fsAsBruce = fsAsDiana = fsAsSupergroupMember = fsAsBob = null; |
| } |
| |
| @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)010750); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testModifyAclEntriesOnlyAccess() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010750); |
| 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)010750); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testModifyAclEntriesMinimal() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010660); |
| 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)010750); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testModifyAclEntriesCustomMask() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010600); |
| 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)011750); |
| 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 { |
| fs.create(path).close(); |
| fs.setPermission(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)010750); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testRemoveAclEntriesOnlyAccess() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010760); |
| 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)010750); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testRemoveAclEntriesMinimal() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010750); |
| 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)011750); |
| 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 Exception { |
| 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)010770); |
| assertAclFeature(true); |
| // restart of the cluster |
| restartCluster(); |
| s = fs.getAclStatus(path); |
| AclEntry[] afterRestart = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(returned, afterRestart); |
| } |
| |
| @Test |
| public void testRemoveDefaultAclOnlyAccess() throws Exception { |
| fs.create(path).close(); |
| fs.setPermission(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)010770); |
| assertAclFeature(true); |
| // restart of the cluster |
| restartCluster(); |
| s = fs.getAclStatus(path); |
| AclEntry[] afterRestart = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(returned, afterRestart); |
| } |
| |
| @Test |
| public void testRemoveDefaultAclOnlyDefault() throws Exception { |
| 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); |
| // restart of the cluster |
| restartCluster(); |
| s = fs.getAclStatus(path); |
| AclEntry[] afterRestart = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(returned, afterRestart); |
| } |
| |
| @Test |
| public void testRemoveDefaultAclMinimal() throws Exception { |
| 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); |
| // restart of the cluster |
| restartCluster(); |
| s = fs.getAclStatus(path); |
| AclEntry[] afterRestart = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(returned, afterRestart); |
| } |
| |
| @Test |
| public void testRemoveDefaultAclStickyBit() throws Exception { |
| 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)011770); |
| assertAclFeature(true); |
| // restart of the cluster |
| restartCluster(); |
| s = fs.getAclStatus(path); |
| AclEntry[] afterRestart = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(returned, afterRestart); |
| } |
| |
| @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 { |
| fs.create(path).close(); |
| fs.setPermission(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 |
| public void testRemoveAclOnlyDefault() 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.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(expected=FileNotFoundException.class) |
| public void testRemoveAclPathNotFound() throws IOException { |
| // Path has not been created. |
| fs.removeAcl(path); |
| } |
| |
| @Test |
| public void testSetAcl() 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); |
| 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)010770); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testSetAclOnlyAccess() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010640); |
| 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)010750); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testSetAclMinimal() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010750); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testSetAclCustomMask() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010670); |
| 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)011770); |
| 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 { |
| fs.create(path).close(); |
| fs.setPermission(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)010700); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testSetPermissionOnlyAccess() throws IOException { |
| fs.create(path).close(); |
| fs.setPermission(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)010600); |
| 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)010700); |
| assertAclFeature(true); |
| } |
| |
| @Test |
| public void testSetPermissionCannotSetAclBit() throws IOException { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| fs.setPermission(path, FsPermission.createImmutable((short)0700)); |
| assertPermission((short)0700); |
| fs.setPermission(path, |
| new FsPermissionExtension(FsPermission. |
| createImmutable((short)0755), true, true)); |
| INode inode = cluster.getNamesystem().getFSDirectory() |
| .getINode(path.toUri().getPath(), DirOp.READ_LINK); |
| assertNotNull(inode); |
| FsPermission perm = inode.getFsPermission(); |
| assertNotNull(perm); |
| assertEquals(0755, perm.toShort()); |
| assertEquals(0755, perm.toExtendedShort()); |
| assertAclFeature(false); |
| } |
| |
| @Test |
| public void testDefaultAclNewFile() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(path, aclSpec); |
| Path filePath = new Path(path, "file1"); |
| fs.create(filePath).close(); |
| AclStatus s = fs.getAclStatus(filePath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(new AclEntry[] { |
| aclEntry(ACCESS, USER, "foo", ALL), |
| aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); |
| assertPermission(filePath, (short)010640); |
| assertAclFeature(filePath, true); |
| } |
| |
| @Test |
| public void testOnlyAccessAclNewFile() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(ACCESS, USER, "foo", ALL)); |
| fs.modifyAclEntries(path, aclSpec); |
| Path filePath = new Path(path, "file1"); |
| fs.create(filePath).close(); |
| AclStatus s = fs.getAclStatus(filePath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(new AclEntry[] { }, returned); |
| assertPermission(filePath, (short)0644); |
| assertAclFeature(filePath, false); |
| } |
| |
| @Test |
| public void testDefaultMinimalAclNewFile() throws Exception { |
| 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); |
| Path filePath = new Path(path, "file1"); |
| fs.create(filePath).close(); |
| AclStatus s = fs.getAclStatus(filePath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(new AclEntry[] { }, returned); |
| assertPermission(filePath, (short)0640); |
| assertAclFeature(filePath, false); |
| } |
| |
| @Test |
| public void testDefaultAclNewDir() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(path, aclSpec); |
| Path dirPath = new Path(path, "dir1"); |
| fs.mkdirs(dirPath); |
| AclStatus s = fs.getAclStatus(dirPath); |
| 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(dirPath, (short)010750); |
| assertAclFeature(dirPath, true); |
| } |
| |
| @Test |
| public void testOnlyAccessAclNewDir() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(ACCESS, USER, "foo", ALL)); |
| fs.modifyAclEntries(path, aclSpec); |
| Path dirPath = new Path(path, "dir1"); |
| fs.mkdirs(dirPath); |
| AclStatus s = fs.getAclStatus(dirPath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(new AclEntry[] { }, returned); |
| assertPermission(dirPath, (short)0755); |
| assertAclFeature(dirPath, false); |
| } |
| |
| @Test |
| public void testDefaultMinimalAclNewDir() throws Exception { |
| 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); |
| Path dirPath = new Path(path, "dir1"); |
| fs.mkdirs(dirPath); |
| AclStatus s = fs.getAclStatus(dirPath); |
| 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(dirPath, (short)010750); |
| assertAclFeature(dirPath, true); |
| } |
| |
| @Test |
| public void testDefaultAclNewFileIntermediate() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(path, aclSpec); |
| Path dirPath = new Path(path, "dir1"); |
| Path filePath = new Path(dirPath, "file1"); |
| fs.create(filePath).close(); |
| AclEntry[] expected = 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) }; |
| AclStatus s = fs.getAclStatus(dirPath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(dirPath, (short)010750); |
| assertAclFeature(dirPath, true); |
| expected = new AclEntry[] { |
| aclEntry(ACCESS, USER, "foo", ALL), |
| aclEntry(ACCESS, GROUP, READ_EXECUTE) }; |
| s = fs.getAclStatus(filePath); |
| returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(filePath, (short)010640); |
| assertAclFeature(filePath, true); |
| } |
| |
| @Test |
| public void testDefaultAclNewDirIntermediate() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(path, aclSpec); |
| Path dirPath = new Path(path, "dir1"); |
| Path subdirPath = new Path(dirPath, "subdir1"); |
| fs.mkdirs(subdirPath); |
| AclEntry[] expected = 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) }; |
| AclStatus s = fs.getAclStatus(dirPath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(dirPath, (short)010750); |
| assertAclFeature(dirPath, true); |
| s = fs.getAclStatus(subdirPath); |
| returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(subdirPath, (short)010750); |
| assertAclFeature(subdirPath, true); |
| } |
| |
| @Test |
| public void testDefaultAclNewSymlinkIntermediate() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750)); |
| Path filePath = new Path(path, "file1"); |
| fs.create(filePath).close(); |
| fs.setPermission(filePath, FsPermission.createImmutable((short)0640)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(path, aclSpec); |
| Path dirPath = new Path(path, "dir1"); |
| Path linkPath = new Path(dirPath, "link1"); |
| fs.createSymlink(filePath, linkPath, true); |
| AclEntry[] expected = 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) }; |
| AclStatus s = fs.getAclStatus(dirPath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(dirPath, (short)010750); |
| assertAclFeature(dirPath, true); |
| expected = new AclEntry[] { }; |
| s = fs.getAclStatus(linkPath); |
| returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(linkPath, (short)0640); |
| assertAclFeature(linkPath, false); |
| s = fs.getAclStatus(filePath); |
| returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(filePath, (short)0640); |
| assertAclFeature(filePath, false); |
| } |
| |
| @Test |
| public void testDefaultAclNewFileWithMode() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0755)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(path, aclSpec); |
| Path filePath = new Path(path, "file1"); |
| int bufferSize = cluster.getConfiguration(0).getInt( |
| CommonConfigurationKeys.IO_FILE_BUFFER_SIZE_KEY, |
| CommonConfigurationKeys.IO_FILE_BUFFER_SIZE_DEFAULT); |
| fs.create(filePath, new FsPermission((short)0740), false, bufferSize, |
| fs.getDefaultReplication(filePath), fs.getDefaultBlockSize(path), null) |
| .close(); |
| AclStatus s = fs.getAclStatus(filePath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(new AclEntry[] { |
| aclEntry(ACCESS, USER, "foo", ALL), |
| aclEntry(ACCESS, GROUP, READ_EXECUTE) }, returned); |
| assertPermission(filePath, (short)010740); |
| assertAclFeature(filePath, true); |
| } |
| |
| @Test |
| public void testDefaultAclNewDirWithMode() throws Exception { |
| FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0755)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(path, aclSpec); |
| Path dirPath = new Path(path, "dir1"); |
| fs.mkdirs(dirPath, new FsPermission((short)0740)); |
| AclStatus s = fs.getAclStatus(dirPath); |
| 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, READ_EXECUTE) }, returned); |
| assertPermission(dirPath, (short)010740); |
| assertAclFeature(dirPath, true); |
| } |
| |
| @Test |
| public void testDefaultAclRenamedFile() throws Exception { |
| Path dirPath = new Path(path, "dir"); |
| FileSystem.mkdirs(fs, dirPath, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(dirPath, aclSpec); |
| Path filePath = new Path(path, "file1"); |
| fs.create(filePath).close(); |
| fs.setPermission(filePath, FsPermission.createImmutable((short)0640)); |
| Path renamedFilePath = new Path(dirPath, "file1"); |
| fs.rename(filePath, renamedFilePath); |
| AclEntry[] expected = new AclEntry[] { }; |
| AclStatus s = fs.getAclStatus(renamedFilePath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(renamedFilePath, (short)0640); |
| assertAclFeature(renamedFilePath, false); |
| } |
| |
| @Test |
| public void testDefaultAclRenamedDir() throws Exception { |
| Path dirPath = new Path(path, "dir"); |
| FileSystem.mkdirs(fs, dirPath, FsPermission.createImmutable((short)0750)); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "foo", ALL)); |
| fs.setAcl(dirPath, aclSpec); |
| Path subdirPath = new Path(path, "subdir"); |
| FileSystem.mkdirs(fs, subdirPath, FsPermission.createImmutable((short)0750)); |
| Path renamedSubdirPath = new Path(dirPath, "subdir"); |
| fs.rename(subdirPath, renamedSubdirPath); |
| AclEntry[] expected = new AclEntry[] { }; |
| AclStatus s = fs.getAclStatus(renamedSubdirPath); |
| AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); |
| assertArrayEquals(expected, returned); |
| assertPermission(renamedSubdirPath, (short)0750); |
| assertAclFeature(renamedSubdirPath, false); |
| } |
| |
| @Test |
| public void testSkipAclEnforcementPermsDisabled() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| fsAsBruce.modifyAclEntries(bruceFile, Lists.newArrayList( |
| aclEntry(ACCESS, USER, "diana", NONE))); |
| assertFilePermissionDenied(fsAsDiana, DIANA, bruceFile); |
| try { |
| conf.setBoolean(DFSConfigKeys.DFS_PERMISSIONS_ENABLED_KEY, false); |
| restartCluster(); |
| assertFilePermissionGranted(fsAsDiana, DIANA, bruceFile); |
| } finally { |
| conf.setBoolean(DFSConfigKeys.DFS_PERMISSIONS_ENABLED_KEY, true); |
| restartCluster(); |
| } |
| } |
| |
| @Test |
| public void testSkipAclEnforcementSuper() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| fsAsBruce.modifyAclEntries(bruceFile, Lists.newArrayList( |
| aclEntry(ACCESS, USER, "diana", NONE))); |
| assertFilePermissionGranted(fs, DIANA, bruceFile); |
| assertFilePermissionGranted(fsAsBruce, DIANA, bruceFile); |
| assertFilePermissionDenied(fsAsDiana, DIANA, bruceFile); |
| assertFilePermissionGranted(fsAsSupergroupMember, SUPERGROUP_MEMBER, |
| bruceFile); |
| } |
| |
| @Test |
| public void testModifyAclEntriesMustBeOwnerOrSuper() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(ACCESS, USER, "diana", ALL)); |
| fsAsBruce.modifyAclEntries(bruceFile, aclSpec); |
| fs.modifyAclEntries(bruceFile, aclSpec); |
| fsAsSupergroupMember.modifyAclEntries(bruceFile, aclSpec); |
| exception.expect(AccessControlException.class); |
| fsAsDiana.modifyAclEntries(bruceFile, aclSpec); |
| } |
| |
| @Test |
| public void testRemoveAclEntriesMustBeOwnerOrSuper() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(ACCESS, USER, "diana")); |
| fsAsBruce.removeAclEntries(bruceFile, aclSpec); |
| fs.removeAclEntries(bruceFile, aclSpec); |
| fsAsSupergroupMember.removeAclEntries(bruceFile, aclSpec); |
| exception.expect(AccessControlException.class); |
| fsAsDiana.removeAclEntries(bruceFile, aclSpec); |
| } |
| |
| @Test |
| public void testRemoveDefaultAclMustBeOwnerOrSuper() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| fsAsBruce.removeDefaultAcl(bruceFile); |
| fs.removeDefaultAcl(bruceFile); |
| fsAsSupergroupMember.removeDefaultAcl(bruceFile); |
| exception.expect(AccessControlException.class); |
| fsAsDiana.removeDefaultAcl(bruceFile); |
| } |
| |
| @Test |
| public void testRemoveAclMustBeOwnerOrSuper() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| fsAsBruce.removeAcl(bruceFile); |
| fs.removeAcl(bruceFile); |
| fsAsSupergroupMember.removeAcl(bruceFile); |
| exception.expect(AccessControlException.class); |
| fsAsDiana.removeAcl(bruceFile); |
| } |
| |
| @Test |
| public void testSetAclMustBeOwnerOrSuper() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(ACCESS, USER, READ_WRITE), |
| aclEntry(ACCESS, USER, "diana", READ_WRITE), |
| aclEntry(ACCESS, GROUP, READ), |
| aclEntry(ACCESS, OTHER, READ)); |
| fsAsBruce.setAcl(bruceFile, aclSpec); |
| fs.setAcl(bruceFile, aclSpec); |
| fsAsSupergroupMember.setAcl(bruceFile, aclSpec); |
| exception.expect(AccessControlException.class); |
| fsAsDiana.setAcl(bruceFile, aclSpec); |
| } |
| |
| @Test |
| public void testGetAclStatusRequiresTraverseOrSuper() throws Exception { |
| Path bruceDir = new Path(path, "bruce"); |
| Path bruceFile = new Path(bruceDir, "file"); |
| fs.mkdirs(bruceDir); |
| fs.setOwner(bruceDir, "bruce", null); |
| fsAsBruce.create(bruceFile).close(); |
| fsAsBruce.setAcl(bruceDir, Lists.newArrayList( |
| aclEntry(ACCESS, USER, ALL), |
| aclEntry(ACCESS, USER, "diana", READ), |
| aclEntry(ACCESS, GROUP, NONE), |
| aclEntry(ACCESS, OTHER, NONE))); |
| fsAsBruce.getAclStatus(bruceFile); |
| fs.getAclStatus(bruceFile); |
| fsAsSupergroupMember.getAclStatus(bruceFile); |
| exception.expect(AccessControlException.class); |
| fsAsDiana.getAclStatus(bruceFile); |
| } |
| |
| @Test |
| public void testAccess() throws IOException, InterruptedException { |
| Path p1 = new Path("/p1"); |
| fs.mkdirs(p1); |
| fs.setOwner(p1, BRUCE.getShortUserName(), "groupX"); |
| fsAsBruce.setAcl(p1, Lists.newArrayList( |
| aclEntry(ACCESS, USER, READ), |
| aclEntry(ACCESS, USER, "bruce", READ), |
| aclEntry(ACCESS, GROUP, NONE), |
| aclEntry(ACCESS, OTHER, NONE))); |
| fsAsBruce.access(p1, FsAction.READ); |
| try { |
| fsAsBruce.access(p1, FsAction.WRITE); |
| fail("The access call should have failed."); |
| } catch (AccessControlException e) { |
| // expected |
| } |
| |
| Path badPath = new Path("/bad/bad"); |
| try { |
| fsAsBruce.access(badPath, FsAction.READ); |
| fail("The access call should have failed"); |
| } catch (FileNotFoundException e) { |
| // expected |
| } |
| |
| // Add a named group entry with only READ access |
| fsAsBruce.modifyAclEntries(p1, Lists.newArrayList( |
| aclEntry(ACCESS, GROUP, "groupY", READ))); |
| // Now bob should have read access, but not write |
| fsAsBob.access(p1, READ); |
| try { |
| fsAsBob.access(p1, WRITE); |
| fail("The access call should have failed."); |
| } catch (AccessControlException e) { |
| // expected; |
| } |
| |
| // Add another named group entry with WRITE access |
| fsAsBruce.modifyAclEntries(p1, Lists.newArrayList( |
| aclEntry(ACCESS, GROUP, "groupZ", WRITE))); |
| // Now bob should have write access |
| fsAsBob.access(p1, WRITE); |
| |
| // Add a named user entry to deny bob |
| fsAsBruce.modifyAclEntries(p1, |
| Lists.newArrayList(aclEntry(ACCESS, USER, "bob", NONE))); |
| |
| try { |
| fsAsBob.access(p1, READ); |
| fail("The access call should have failed."); |
| } catch (AccessControlException e) { |
| // expected; |
| } |
| } |
| |
| @Test |
| public void testEffectiveAccess() throws Exception { |
| Path p1 = new Path("/testEffectiveAccess"); |
| fs.mkdirs(p1); |
| // give all access at first |
| fs.setPermission(p1, FsPermission.valueOf("-rwxrwxrwx")); |
| AclStatus aclStatus = fs.getAclStatus(p1); |
| assertEquals("Entries should be empty", 0, aclStatus.getEntries().size()); |
| assertEquals("Permission should be carried by AclStatus", |
| fs.getFileStatus(p1).getPermission(), aclStatus.getPermission()); |
| |
| // Add a named entries with all access |
| fs.modifyAclEntries(p1, Lists.newArrayList( |
| aclEntry(ACCESS, USER, "bruce", ALL), |
| aclEntry(ACCESS, GROUP, "groupY", ALL))); |
| aclStatus = fs.getAclStatus(p1); |
| assertEquals("Entries should contain owner group entry also", 3, aclStatus |
| .getEntries().size()); |
| |
| // restrict the access |
| fs.setPermission(p1, FsPermission.valueOf("-rwxr-----")); |
| // latest permissions should be reflected as effective permission |
| aclStatus = fs.getAclStatus(p1); |
| List<AclEntry> entries = aclStatus.getEntries(); |
| for (AclEntry aclEntry : entries) { |
| if (aclEntry.getName() != null || aclEntry.getType() == GROUP) { |
| assertEquals(FsAction.ALL, aclEntry.getPermission()); |
| assertEquals(FsAction.READ, aclStatus.getEffectivePermission(aclEntry)); |
| } |
| } |
| fsAsBruce.access(p1, READ); |
| try { |
| fsAsBruce.access(p1, WRITE); |
| fail("Access should not be given"); |
| } catch (AccessControlException e) { |
| // expected |
| } |
| fsAsBob.access(p1, READ); |
| try { |
| fsAsBob.access(p1, WRITE); |
| fail("Access should not be given"); |
| } catch (AccessControlException e) { |
| // expected |
| } |
| } |
| |
| /** |
| * Verify the de-duplication of AclFeatures with same entries. |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testDeDuplication() throws Exception { |
| // This test needs to verify the count of the references which is held by |
| // static data structure. So shutting down entire cluster to get the fresh |
| // data. |
| shutdown(); |
| AclStorage.getUniqueAclFeatures().clear(); |
| startCluster(); |
| setUp(); |
| int currentSize = 0; |
| Path p1 = new Path("/testDeduplication"); |
| { |
| // unique default AclEntries for this test |
| List<AclEntry> aclSpec = Lists.newArrayList( |
| aclEntry(DEFAULT, USER, "testdeduplicateuser", ALL), |
| aclEntry(DEFAULT, GROUP, "testdeduplicategroup", ALL)); |
| fs.mkdirs(p1); |
| fs.modifyAclEntries(p1, aclSpec); |
| assertEquals("One more ACL feature should be unique", currentSize + 1, |
| AclStorage.getUniqueAclFeatures().getUniqueElementsSize()); |
| currentSize++; |
| } |
| Path child1 = new Path(p1, "child1"); |
| AclFeature child1AclFeature; |
| { |
| // new child dir should copy entries from its parent. |
| fs.mkdirs(child1); |
| assertEquals("One more ACL feature should be unique", currentSize + 1, |
| AclStorage.getUniqueAclFeatures().getUniqueElementsSize()); |
| child1AclFeature = getAclFeature(child1, cluster); |
| assertEquals("Reference count should be 1", 1, |
| child1AclFeature.getRefCount()); |
| currentSize++; |
| } |
| Path child2 = new Path(p1, "child2"); |
| { |
| // new child dir should copy entries from its parent. But all entries are |
| // same as its sibling without any more acl changes. |
| fs.mkdirs(child2); |
| assertEquals("existing AclFeature should be re-used", currentSize, |
| AclStorage.getUniqueAclFeatures().getUniqueElementsSize()); |
| AclFeature child2AclFeature = getAclFeature(child1, cluster); |
| assertSame("Same Aclfeature should be re-used", child1AclFeature, |
| child2AclFeature); |
| assertEquals("Reference count should be 2", 2, |
| child2AclFeature.getRefCount()); |
| } |
| { |
| // modification of ACL on should decrement the original reference count |
| // and increase new one. |
| List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, |
| "user1", ALL)); |
| fs.modifyAclEntries(child1, aclSpec); |
| AclFeature modifiedAclFeature = getAclFeature(child1, cluster); |
| assertEquals("Old Reference count should be 1", 1, |
| child1AclFeature.getRefCount()); |
| assertEquals("New Reference count should be 1", 1, |
| modifiedAclFeature.getRefCount()); |
| |
| // removing the new added ACL entry should refer to old ACLfeature |
| AclEntry aclEntry = new AclEntry.Builder().setScope(ACCESS).setType(USER) |
| .setName("user1").build(); |
| fs.removeAclEntries(child1, Lists.newArrayList(aclEntry)); |
| assertEquals("Old Reference count should be 2 again", 2, |
| child1AclFeature.getRefCount()); |
| assertEquals("New Reference count should be 0", 0, |
| modifiedAclFeature.getRefCount()); |
| } |
| { |
| // verify the reference count on deletion of Acls |
| fs.removeAcl(child2); |
| assertEquals("Reference count should be 1", 1, |
| child1AclFeature.getRefCount()); |
| } |
| { |
| // verify the reference count on deletion of dir with ACL |
| fs.delete(child1, true); |
| assertEquals("Reference count should be 0", 0, |
| child1AclFeature.getRefCount()); |
| } |
| |
| Path file1 = new Path(p1, "file1"); |
| Path file2 = new Path(p1, "file2"); |
| AclFeature fileAclFeature; |
| { |
| // Using same reference on creation of file |
| fs.create(file1).close(); |
| fileAclFeature = getAclFeature(file1, cluster); |
| assertEquals("Reference count should be 1", 1, |
| fileAclFeature.getRefCount()); |
| fs.create(file2).close(); |
| assertEquals("Reference count should be 2", 2, |
| fileAclFeature.getRefCount()); |
| } |
| { |
| // modifying ACLs on file should decrease the reference count on old |
| // instance and increase on the new instance |
| List<AclEntry> aclSpec = Lists.newArrayList(aclEntry(ACCESS, USER, |
| "user1", ALL)); |
| // adding new ACL entry |
| fs.modifyAclEntries(file1, aclSpec); |
| AclFeature modifiedFileAcl = getAclFeature(file1, cluster); |
| assertEquals("Old Reference count should be 1", 1, |
| fileAclFeature.getRefCount()); |
| assertEquals("New Reference count should be 1", 1, |
| modifiedFileAcl.getRefCount()); |
| |
| // removing the new added ACL entry should refer to old ACLfeature |
| AclEntry aclEntry = new AclEntry.Builder().setScope(ACCESS).setType(USER) |
| .setName("user1").build(); |
| fs.removeAclEntries(file1, Lists.newArrayList(aclEntry)); |
| assertEquals("Old Reference count should be 2", 2, |
| fileAclFeature.getRefCount()); |
| assertEquals("New Reference count should be 0", 0, |
| modifiedFileAcl.getRefCount()); |
| } |
| { |
| // reference count should be decreased on deletion of files with ACLs |
| fs.delete(file2, true); |
| assertEquals("Reference count should be decreased on delete of the file", |
| 1, fileAclFeature.getRefCount()); |
| fs.delete(file1, true); |
| assertEquals("Reference count should be decreased on delete of the file", |
| 0, fileAclFeature.getRefCount()); |
| |
| // On reference count reaches 0 instance should be removed from map |
| fs.create(file1).close(); |
| AclFeature newFileAclFeature = getAclFeature(file1, cluster); |
| assertNotSame("Instance should be different on reference count 0", |
| fileAclFeature, newFileAclFeature); |
| fileAclFeature = newFileAclFeature; |
| } |
| Map<AclFeature, Integer> restartRefCounter = new HashMap<>(); |
| // Restart the Namenode to check the references. |
| // Here reference counts will not be same after restart because, while |
| // shutting down namenode will not call any removal of AclFeature. |
| // However this is applicable only in case of tests as in real-cluster JVM |
| // itself will be new. |
| List<AclFeature> entriesBeforeRestart = AclStorage.getUniqueAclFeatures() |
| .getEntries(); |
| { |
| //restart by loading edits |
| for (AclFeature aclFeature : entriesBeforeRestart) { |
| restartRefCounter.put(aclFeature, aclFeature.getRefCount()); |
| } |
| cluster.restartNameNode(true); |
| List<AclFeature> entriesAfterRestart = AclStorage.getUniqueAclFeatures() |
| .getEntries(); |
| assertEquals("Entries before and after should be same", |
| entriesBeforeRestart, entriesAfterRestart); |
| for (AclFeature aclFeature : entriesAfterRestart) { |
| int before = restartRefCounter.get(aclFeature); |
| assertEquals("ReferenceCount After Restart should be doubled", |
| before * 2, aclFeature.getRefCount()); |
| } |
| } |
| { |
| //restart by loading fsimage |
| cluster.getNameNodeRpc() |
| .setSafeMode(SafeModeAction.SAFEMODE_ENTER, false); |
| cluster.getNameNodeRpc().saveNamespace(); |
| cluster.getNameNodeRpc() |
| .setSafeMode(SafeModeAction.SAFEMODE_LEAVE, false); |
| cluster.restartNameNode(true); |
| List<AclFeature> entriesAfterRestart = AclStorage.getUniqueAclFeatures() |
| .getEntries(); |
| assertEquals("Entries before and after should be same", |
| entriesBeforeRestart, entriesAfterRestart); |
| for (AclFeature aclFeature : entriesAfterRestart) { |
| int before = restartRefCounter.get(aclFeature); |
| assertEquals("ReferenceCount After 2 Restarts should be tripled", |
| before * 3, aclFeature.getRefCount()); |
| } |
| } |
| } |
| |
| /** |
| * Creates a FileSystem for the super-user. |
| * |
| * @return FileSystem for super-user |
| * @throws Exception if creation fails |
| */ |
| protected FileSystem createFileSystem() throws Exception { |
| return cluster.getFileSystem(); |
| } |
| |
| /** |
| * Creates a FileSystem for a specific user. |
| * |
| * @param user UserGroupInformation specific user |
| * @return FileSystem for specific user |
| * @throws Exception if creation fails |
| */ |
| protected FileSystem createFileSystem(UserGroupInformation user) |
| throws Exception { |
| return DFSTestUtil.getFileSystemAs(user, cluster.getConfiguration(0)); |
| } |
| |
| /** |
| * Initializes all FileSystem instances used in the tests. |
| * |
| * @throws Exception if initialization fails |
| */ |
| private void initFileSystems() throws Exception { |
| fs = createFileSystem(); |
| fsAsBruce = createFileSystem(BRUCE); |
| fsAsDiana = createFileSystem(DIANA); |
| fsAsBob = createFileSystem(BOB); |
| fsAsSupergroupMember = createFileSystem(SUPERGROUP_MEMBER); |
| } |
| |
| /** |
| * Restarts the cluster without formatting, so all data is preserved. |
| * |
| * @throws Exception if restart fails |
| */ |
| private void restartCluster() throws Exception { |
| destroyFileSystems(); |
| shutdown(); |
| cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).format(false) |
| .build(); |
| cluster.waitActive(); |
| initFileSystems(); |
| } |
| |
| /** |
| * 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 { |
| assertAclFeature(path, expectAclFeature); |
| } |
| |
| private static void assertAclFeature(Path pathToCheck, |
| boolean expectAclFeature) throws IOException { |
| assertAclFeature(cluster, pathToCheck, expectAclFeature); |
| } |
| |
| /** |
| * Asserts whether or not the inode for a specific path has an AclFeature. |
| * |
| * @param miniCluster the cluster into which the path resides |
| * @param pathToCheck Path inode to check |
| * @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 |
| */ |
| public static void assertAclFeature(final MiniDFSCluster miniCluster, |
| Path pathToCheck, boolean expectAclFeature) throws IOException { |
| AclFeature aclFeature = getAclFeature(pathToCheck, miniCluster); |
| if (expectAclFeature) { |
| assertNotNull(aclFeature); |
| // Intentionally capturing a reference to the entries, not using nested |
| // calls. This way, we get compile-time enforcement that the entries are |
| // stored in an ImmutableList. |
| ImmutableList<AclEntry> entries = AclStorage |
| .getEntriesFromAclFeature(aclFeature); |
| assertFalse(entries.isEmpty()); |
| } else { |
| assertNull(aclFeature); |
| } |
| } |
| |
| /** |
| * Get AclFeature for the path |
| */ |
| public static AclFeature getAclFeature(Path pathToCheck, |
| MiniDFSCluster cluster) throws IOException { |
| INode inode = cluster.getNamesystem().getFSDirectory() |
| .getINode(pathToCheck.toUri().getPath(), DirOp.READ_LINK); |
| assertNotNull(inode); |
| AclFeature aclFeature = inode.getAclFeature(); |
| return 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 void assertPermission(short perm) throws IOException { |
| assertPermission(path, perm); |
| } |
| |
| /** |
| * Asserts the value of the FsPermission bits on the inode of a specific path. |
| * |
| * @param pathToCheck Path inode to check |
| * @param perm short expected permission bits |
| * @throws IOException thrown if there is an I/O error |
| */ |
| private void assertPermission(Path pathToCheck, short perm) |
| throws IOException { |
| AclTestHelpers.assertPermission(fs, pathToCheck, perm); |
| } |
| } |