HDFS-6603. Add XAttr with ACL test. Contributed by Stephen Chu.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1607239 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
58e398f31d
commit
c89bf0184d
|
@ -482,6 +482,8 @@ Release 2.5.0 - UNRELEASED
|
||||||
HDFS-6572. Add an option to the NameNode that prints the software and
|
HDFS-6572. Add an option to the NameNode that prints the software and
|
||||||
on-disk image versions. (Charles Lamb via cnauroth)
|
on-disk image versions. (Charles Lamb via cnauroth)
|
||||||
|
|
||||||
|
HDFS-6603. Add XAttr with ACL test. (Stephen Chu via cnauroth)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
HDFS-6214. Webhdfs has poor throughput for files >2GB (daryn)
|
HDFS-6214. Webhdfs has poor throughput for files >2GB (daryn)
|
||||||
|
|
|
@ -32,12 +32,20 @@ import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.XAttrSetFlag;
|
import org.apache.hadoop.fs.XAttrSetFlag;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||||
|
import org.apache.hadoop.hdfs.DFSTestUtil;
|
||||||
import org.apache.hadoop.hdfs.HdfsConfiguration;
|
import org.apache.hadoop.hdfs.HdfsConfiguration;
|
||||||
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
||||||
import org.apache.hadoop.io.IOUtils;
|
import org.apache.hadoop.io.IOUtils;
|
||||||
|
import org.apache.hadoop.security.AccessControlException;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.ipc.RemoteException;
|
import org.apache.hadoop.ipc.RemoteException;
|
||||||
import org.apache.hadoop.test.GenericTestUtils;
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.fs.permission.AclEntryScope.ACCESS;
|
||||||
|
import static org.apache.hadoop.fs.permission.AclEntryType.USER;
|
||||||
|
import static org.apache.hadoop.fs.permission.FsAction.ALL;
|
||||||
|
import static org.apache.hadoop.fs.permission.FsAction.READ;
|
||||||
|
import static org.apache.hadoop.hdfs.server.namenode.AclTestHelpers.aclEntry;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -60,7 +68,7 @@ public class FSXAttrBaseTest {
|
||||||
protected static MiniDFSCluster dfsCluster;
|
protected static MiniDFSCluster dfsCluster;
|
||||||
protected static Configuration conf;
|
protected static Configuration conf;
|
||||||
private static int pathCount = 0;
|
private static int pathCount = 0;
|
||||||
private static Path path;
|
protected static Path path;
|
||||||
|
|
||||||
// XAttrs
|
// XAttrs
|
||||||
protected static final String name1 = "user.a1";
|
protected static final String name1 = "user.a1";
|
||||||
|
@ -73,10 +81,16 @@ public class FSXAttrBaseTest {
|
||||||
|
|
||||||
protected FileSystem fs;
|
protected FileSystem fs;
|
||||||
|
|
||||||
|
private static final UserGroupInformation BRUCE =
|
||||||
|
UserGroupInformation.createUserForTesting("bruce", new String[] { });
|
||||||
|
private static final UserGroupInformation DIANA =
|
||||||
|
UserGroupInformation.createUserForTesting("diana", new String[] { });
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void init() throws Exception {
|
public static void init() throws Exception {
|
||||||
conf = new HdfsConfiguration();
|
conf = new HdfsConfiguration();
|
||||||
conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_XATTRS_ENABLED_KEY, true);
|
conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_XATTRS_ENABLED_KEY, true);
|
||||||
|
conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, true);
|
||||||
conf.setInt(DFSConfigKeys.DFS_NAMENODE_MAX_XATTRS_PER_INODE_KEY, 3);
|
conf.setInt(DFSConfigKeys.DFS_NAMENODE_MAX_XATTRS_PER_INODE_KEY, 3);
|
||||||
conf.setInt(DFSConfigKeys.DFS_NAMENODE_MAX_XATTR_SIZE_KEY, MAX_SIZE);
|
conf.setInt(DFSConfigKeys.DFS_NAMENODE_MAX_XATTR_SIZE_KEY, MAX_SIZE);
|
||||||
initCluster(true);
|
initCluster(true);
|
||||||
|
@ -388,6 +402,21 @@ public class FSXAttrBaseTest {
|
||||||
fs.removeXAttr(path, name3);
|
fs.removeXAttr(path, name3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 120000)
|
||||||
|
public void testRenameFileWithXAttr() throws Exception {
|
||||||
|
FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750));
|
||||||
|
fs.setXAttr(path, name1, value1, EnumSet.of(XAttrSetFlag.CREATE));
|
||||||
|
fs.setXAttr(path, name2, value2, EnumSet.of(XAttrSetFlag.CREATE));
|
||||||
|
Path renamePath = new Path(path.toString() + "-rename");
|
||||||
|
fs.rename(path, renamePath);
|
||||||
|
Map<String, byte[]> xattrs = fs.getXAttrs(renamePath);
|
||||||
|
Assert.assertEquals(xattrs.size(), 2);
|
||||||
|
Assert.assertArrayEquals(value1, xattrs.get(name1));
|
||||||
|
Assert.assertArrayEquals(value2, xattrs.get(name2));
|
||||||
|
fs.removeXAttr(renamePath, name1);
|
||||||
|
fs.removeXAttr(renamePath, name2);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the listXAttrs api.
|
* Test the listXAttrs api.
|
||||||
* listXAttrs on a path that doesn't exist.
|
* listXAttrs on a path that doesn't exist.
|
||||||
|
@ -536,6 +565,50 @@ public class FSXAttrBaseTest {
|
||||||
Assert.assertArrayEquals(value2, xattrs.get(name2));
|
Assert.assertArrayEquals(value2, xattrs.get(name2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 120000)
|
||||||
|
public void testXAttrAcl() throws Exception {
|
||||||
|
FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short) 0750));
|
||||||
|
fs.setOwner(path, BRUCE.getUserName(), null);
|
||||||
|
FileSystem fsAsBruce = createFileSystem(BRUCE);
|
||||||
|
FileSystem fsAsDiana = createFileSystem(DIANA);
|
||||||
|
fsAsBruce.setXAttr(path, name1, value1);
|
||||||
|
|
||||||
|
Map<String, byte[]> xattrs;
|
||||||
|
try {
|
||||||
|
xattrs = fsAsDiana.getXAttrs(path);
|
||||||
|
Assert.fail("Diana should not have read access to get xattrs");
|
||||||
|
} catch (AccessControlException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give Diana read permissions to the path
|
||||||
|
fsAsBruce.modifyAclEntries(path, Lists.newArrayList(
|
||||||
|
aclEntry(ACCESS, USER, DIANA.getUserName(), READ)));
|
||||||
|
xattrs = fsAsDiana.getXAttrs(path);
|
||||||
|
Assert.assertArrayEquals(value1, xattrs.get(name1));
|
||||||
|
|
||||||
|
try {
|
||||||
|
fsAsDiana.removeXAttr(path, name1);
|
||||||
|
Assert.fail("Diana should not have write access to remove xattrs");
|
||||||
|
} catch (AccessControlException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fsAsDiana.setXAttr(path, name2, value2);
|
||||||
|
Assert.fail("Diana should not have write access to set xattrs");
|
||||||
|
} catch (AccessControlException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
fsAsBruce.modifyAclEntries(path, Lists.newArrayList(
|
||||||
|
aclEntry(ACCESS, USER, DIANA.getUserName(), ALL)));
|
||||||
|
fsAsDiana.setXAttr(path, name2, value2);
|
||||||
|
Assert.assertArrayEquals(value2, fsAsDiana.getXAttrs(path).get(name2));
|
||||||
|
fsAsDiana.removeXAttr(path, name1);
|
||||||
|
fsAsDiana.removeXAttr(path, name2);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a FileSystem for the super-user.
|
* Creates a FileSystem for the super-user.
|
||||||
*
|
*
|
||||||
|
@ -546,6 +619,18 @@ public class FSXAttrBaseTest {
|
||||||
return dfsCluster.getFileSystem();
|
return dfsCluster.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, conf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes all FileSystem instances used in the tests.
|
* Initializes all FileSystem instances used in the tests.
|
||||||
*
|
*
|
||||||
|
|
|
@ -49,6 +49,8 @@ public class TestFSImageWithXAttr {
|
||||||
private static final byte[] newValue1 = {0x31, 0x31, 0x31};
|
private static final byte[] newValue1 = {0x31, 0x31, 0x31};
|
||||||
private static final String name2 = "user.a2";
|
private static final String name2 = "user.a2";
|
||||||
private static final byte[] value2 = {0x37, 0x38, 0x39};
|
private static final byte[] value2 = {0x37, 0x38, 0x39};
|
||||||
|
private static final String name3 = "user.a3";
|
||||||
|
private static final byte[] value3 = {};
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() throws IOException {
|
public static void setUp() throws IOException {
|
||||||
|
@ -70,25 +72,29 @@ public class TestFSImageWithXAttr {
|
||||||
|
|
||||||
fs.setXAttr(path, name1, value1, EnumSet.of(XAttrSetFlag.CREATE));
|
fs.setXAttr(path, name1, value1, EnumSet.of(XAttrSetFlag.CREATE));
|
||||||
fs.setXAttr(path, name2, value2, EnumSet.of(XAttrSetFlag.CREATE));
|
fs.setXAttr(path, name2, value2, EnumSet.of(XAttrSetFlag.CREATE));
|
||||||
|
fs.setXAttr(path, name3, null, EnumSet.of(XAttrSetFlag.CREATE));
|
||||||
|
|
||||||
restart(fs, persistNamespace);
|
restart(fs, persistNamespace);
|
||||||
|
|
||||||
Map<String, byte[]> xattrs = fs.getXAttrs(path);
|
Map<String, byte[]> xattrs = fs.getXAttrs(path);
|
||||||
Assert.assertEquals(xattrs.size(), 2);
|
Assert.assertEquals(xattrs.size(), 3);
|
||||||
Assert.assertArrayEquals(value1, xattrs.get(name1));
|
Assert.assertArrayEquals(value1, xattrs.get(name1));
|
||||||
Assert.assertArrayEquals(value2, xattrs.get(name2));
|
Assert.assertArrayEquals(value2, xattrs.get(name2));
|
||||||
|
Assert.assertArrayEquals(value3, xattrs.get(name3));
|
||||||
|
|
||||||
fs.setXAttr(path, name1, newValue1, EnumSet.of(XAttrSetFlag.REPLACE));
|
fs.setXAttr(path, name1, newValue1, EnumSet.of(XAttrSetFlag.REPLACE));
|
||||||
|
|
||||||
restart(fs, persistNamespace);
|
restart(fs, persistNamespace);
|
||||||
|
|
||||||
xattrs = fs.getXAttrs(path);
|
xattrs = fs.getXAttrs(path);
|
||||||
Assert.assertEquals(xattrs.size(), 2);
|
Assert.assertEquals(xattrs.size(), 3);
|
||||||
Assert.assertArrayEquals(newValue1, xattrs.get(name1));
|
Assert.assertArrayEquals(newValue1, xattrs.get(name1));
|
||||||
Assert.assertArrayEquals(value2, xattrs.get(name2));
|
Assert.assertArrayEquals(value2, xattrs.get(name2));
|
||||||
|
Assert.assertArrayEquals(value3, xattrs.get(name3));
|
||||||
|
|
||||||
fs.removeXAttr(path, name1);
|
fs.removeXAttr(path, name1);
|
||||||
fs.removeXAttr(path, name2);
|
fs.removeXAttr(path, name2);
|
||||||
|
fs.removeXAttr(path, name3);
|
||||||
|
|
||||||
restart(fs, persistNamespace);
|
restart(fs, persistNamespace);
|
||||||
xattrs = fs.getXAttrs(path);
|
xattrs = fs.getXAttrs(path);
|
||||||
|
|
|
@ -268,6 +268,18 @@ public class TestXAttrWithSnapshot {
|
||||||
hdfs.setXAttr(snapshotPath, name1, value1);
|
hdfs.setXAttr(snapshotPath, name1, value1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert exception of removing xattr on read-only snapshot.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRemoveXAttrSnapshotPath() throws Exception {
|
||||||
|
FileSystem.mkdirs(hdfs, path, FsPermission.createImmutable((short) 0700));
|
||||||
|
hdfs.setXAttr(path, name1, value1);
|
||||||
|
SnapshotTestHelper.createSnapshot(hdfs, path, snapshotName);
|
||||||
|
exception.expect(SnapshotAccessControlException.class);
|
||||||
|
hdfs.removeXAttr(snapshotPath, name1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assert exception of setting xattr when exceeding quota.
|
* Assert exception of setting xattr when exceeding quota.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -143,6 +143,8 @@ public class TestOfflineImageViewer {
|
||||||
hdfs.mkdirs(xattr);
|
hdfs.mkdirs(xattr);
|
||||||
hdfs.setXAttr(xattr, "user.a1", new byte[]{ 0x31, 0x32, 0x33 });
|
hdfs.setXAttr(xattr, "user.a1", new byte[]{ 0x31, 0x32, 0x33 });
|
||||||
hdfs.setXAttr(xattr, "user.a2", new byte[]{ 0x37, 0x38, 0x39 });
|
hdfs.setXAttr(xattr, "user.a2", new byte[]{ 0x37, 0x38, 0x39 });
|
||||||
|
// OIV should be able to handle empty value XAttrs
|
||||||
|
hdfs.setXAttr(xattr, "user.a3", null);
|
||||||
writtenFiles.put(xattr.toString(), hdfs.getFileStatus(xattr));
|
writtenFiles.put(xattr.toString(), hdfs.getFileStatus(xattr));
|
||||||
|
|
||||||
// Write results to the fsimage file
|
// Write results to the fsimage file
|
||||||
|
|
Loading…
Reference in New Issue