|
@@ -18,31 +18,42 @@
|
|
|
|
|
|
package org.apache.hadoop.fs.ozone;
|
|
package org.apache.hadoop.fs.ozone;
|
|
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.net.URI;
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+import java.util.Collection;
|
|
|
|
+
|
|
|
|
+import org.junit.Before;
|
|
|
|
+import org.junit.Test;
|
|
|
|
+import org.junit.runner.RunWith;
|
|
|
|
+import org.junit.runners.Parameterized;
|
|
|
|
+import org.junit.runners.Parameterized.Parameters;
|
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
import org.apache.commons.lang.RandomStringUtils;
|
|
import org.apache.commons.lang.RandomStringUtils;
|
|
|
|
+import org.junit.After;
|
|
|
|
+
|
|
|
|
+import org.apache.hadoop.conf.OzoneConfiguration;
|
|
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
|
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
|
-import org.apache.hadoop.fs.FileSystem;
|
|
|
|
|
|
+import org.apache.hadoop.fs.FSDataInputStream;
|
|
|
|
+import org.apache.hadoop.fs.FSDataOutputStream;
|
|
import org.apache.hadoop.fs.FileStatus;
|
|
import org.apache.hadoop.fs.FileStatus;
|
|
|
|
+import org.apache.hadoop.fs.FileSystem;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.Path;
|
|
-import org.apache.hadoop.fs.FSDataOutputStream;
|
|
|
|
-import org.apache.hadoop.fs.FSDataInputStream;
|
|
|
|
import org.apache.hadoop.hdfs.server.datanode.DataNode;
|
|
import org.apache.hadoop.hdfs.server.datanode.DataNode;
|
|
import org.apache.hadoop.hdfs.server.datanode.ObjectStoreHandler;
|
|
import org.apache.hadoop.hdfs.server.datanode.ObjectStoreHandler;
|
|
import org.apache.hadoop.ozone.MiniOzoneClassicCluster;
|
|
import org.apache.hadoop.ozone.MiniOzoneClassicCluster;
|
|
-import org.apache.hadoop.conf.OzoneConfiguration;
|
|
|
|
import org.apache.hadoop.ozone.OzoneConsts;
|
|
import org.apache.hadoop.ozone.OzoneConsts;
|
|
-import org.apache.hadoop.ozone.client.rest.OzoneException;
|
|
|
|
import org.apache.hadoop.ozone.web.handlers.BucketArgs;
|
|
import org.apache.hadoop.ozone.web.handlers.BucketArgs;
|
|
import org.apache.hadoop.ozone.web.handlers.UserArgs;
|
|
import org.apache.hadoop.ozone.web.handlers.UserArgs;
|
|
import org.apache.hadoop.ozone.web.handlers.VolumeArgs;
|
|
import org.apache.hadoop.ozone.web.handlers.VolumeArgs;
|
|
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
|
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
|
import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
|
import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
|
|
|
+import org.apache.hadoop.security.UserGroupInformation;
|
|
import org.apache.hadoop.util.Time;
|
|
import org.apache.hadoop.util.Time;
|
|
-import org.junit.BeforeClass;
|
|
|
|
-import org.junit.AfterClass;
|
|
|
|
-import org.junit.Test;
|
|
|
|
-import org.junit.Assert;
|
|
|
|
|
|
|
|
-import java.io.IOException;
|
|
|
|
|
|
+import static org.apache.hadoop.fs.ozone.Constants.OZONE_DEFAULT_USER;
|
|
|
|
+import static org.junit.Assert.assertEquals;
|
|
|
|
+import static org.junit.Assert.assertTrue;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Test OzoneFileSystem Interfaces.
|
|
* Test OzoneFileSystem Interfaces.
|
|
@@ -50,13 +61,42 @@ import java.io.IOException;
|
|
* This test will test the various interfaces i.e.
|
|
* This test will test the various interfaces i.e.
|
|
* create, read, write, getFileStatus
|
|
* create, read, write, getFileStatus
|
|
*/
|
|
*/
|
|
|
|
+@RunWith(Parameterized.class)
|
|
public class TestOzoneFileInterfaces {
|
|
public class TestOzoneFileInterfaces {
|
|
|
|
+
|
|
|
|
+ private String rootPath;
|
|
|
|
+ private String userName;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Parameter class to set absolute url/defaultFS handling.
|
|
|
|
+ * <p>
|
|
|
|
+ * Hadoop file systems could be used in multiple ways: Using the defaultfs
|
|
|
|
+ * and file path without the schema, or use absolute url-s even with
|
|
|
|
+ * different defaultFS. This parameter matrix would test both the use cases.
|
|
|
|
+ */
|
|
|
|
+ @Parameters
|
|
|
|
+ public static Collection<Object[]> data() {
|
|
|
|
+ return Arrays.asList(new Object[][] {{false, true}, {true, false}});
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean setDefaultFs;
|
|
|
|
+
|
|
|
|
+ private boolean useAbsolutePath;
|
|
|
|
+
|
|
private static MiniOzoneClassicCluster cluster = null;
|
|
private static MiniOzoneClassicCluster cluster = null;
|
|
|
|
+
|
|
private static FileSystem fs;
|
|
private static FileSystem fs;
|
|
|
|
+
|
|
private static StorageHandler storageHandler;
|
|
private static StorageHandler storageHandler;
|
|
|
|
|
|
- @BeforeClass
|
|
|
|
- public static void init() throws IOException, OzoneException {
|
|
|
|
|
|
+ public TestOzoneFileInterfaces(boolean setDefaultFs,
|
|
|
|
+ boolean useAbsolutePath) {
|
|
|
|
+ this.setDefaultFs = setDefaultFs;
|
|
|
|
+ this.useAbsolutePath = useAbsolutePath;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Before
|
|
|
|
+ public void init() throws Exception {
|
|
OzoneConfiguration conf = new OzoneConfiguration();
|
|
OzoneConfiguration conf = new OzoneConfiguration();
|
|
cluster = new MiniOzoneClassicCluster.Builder(conf)
|
|
cluster = new MiniOzoneClassicCluster.Builder(conf)
|
|
.setHandlerType(OzoneConsts.OZONE_HANDLER_DISTRIBUTED).build();
|
|
.setHandlerType(OzoneConsts.OZONE_HANDLER_DISTRIBUTED).build();
|
|
@@ -64,7 +104,7 @@ public class TestOzoneFileInterfaces {
|
|
new ObjectStoreHandler(conf).getStorageHandler();
|
|
new ObjectStoreHandler(conf).getStorageHandler();
|
|
|
|
|
|
// create a volume and a bucket to be used by OzoneFileSystem
|
|
// create a volume and a bucket to be used by OzoneFileSystem
|
|
- String userName = "user" + RandomStringUtils.randomNumeric(5);
|
|
|
|
|
|
+ userName = "user" + RandomStringUtils.randomNumeric(5);
|
|
String adminName = "admin" + RandomStringUtils.randomNumeric(5);
|
|
String adminName = "admin" + RandomStringUtils.randomNumeric(5);
|
|
String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
|
|
String volumeName = "volume" + RandomStringUtils.randomNumeric(5);
|
|
String bucketName = "bucket" + RandomStringUtils.randomNumeric(5);
|
|
String bucketName = "bucket" + RandomStringUtils.randomNumeric(5);
|
|
@@ -82,24 +122,34 @@ public class TestOzoneFileInterfaces {
|
|
int port = dataNode.getInfoPort();
|
|
int port = dataNode.getInfoPort();
|
|
String host = dataNode.getDatanodeHostname();
|
|
String host = dataNode.getDatanodeHostname();
|
|
|
|
|
|
- // Set the fs.defaultFS and start the filesystem
|
|
|
|
- String uri = String.format("%s://%s:%d/%s/%s",
|
|
|
|
- Constants.OZONE_URI_SCHEME, host, port, volumeName, bucketName);
|
|
|
|
- conf.set(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY, uri);
|
|
|
|
- fs = FileSystem.get(conf);
|
|
|
|
|
|
+ rootPath = String
|
|
|
|
+ .format("%s://%s.%s/", Constants.OZONE_URI_SCHEME, bucketName,
|
|
|
|
+ volumeName);
|
|
|
|
+ if (setDefaultFs) {
|
|
|
|
+ // Set the fs.defaultFS and start the filesystem
|
|
|
|
+ conf.set(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY, rootPath);
|
|
|
|
+ fs = FileSystem.get(conf);
|
|
|
|
+ } else {
|
|
|
|
+ fs = FileSystem.get(new URI(rootPath + "/test.txt"), conf);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- @AfterClass
|
|
|
|
- public static void teardown() throws IOException {
|
|
|
|
- fs.close();
|
|
|
|
- storageHandler.close();
|
|
|
|
- cluster.shutdown();
|
|
|
|
|
|
+ @After
|
|
|
|
+ public void teardown() throws IOException {
|
|
|
|
+ IOUtils.closeQuietly(fs);
|
|
|
|
+ IOUtils.closeQuietly(storageHandler);
|
|
|
|
+ IOUtils.closeQuietly(cluster);
|
|
}
|
|
}
|
|
|
|
|
|
@Test
|
|
@Test
|
|
public void testFileSystemInit() throws IOException {
|
|
public void testFileSystemInit() throws IOException {
|
|
- Assert.assertTrue(fs instanceof OzoneFileSystem);
|
|
|
|
- Assert.assertEquals(Constants.OZONE_URI_SCHEME, fs.getUri().getScheme());
|
|
|
|
|
|
+ if (setDefaultFs) {
|
|
|
|
+ assertTrue(
|
|
|
|
+ "The initialized file system is not OzoneFileSysetem but " +
|
|
|
|
+ fs.getClass(),
|
|
|
|
+ fs instanceof OzoneFileSystem);
|
|
|
|
+ assertEquals(Constants.OZONE_URI_SCHEME, fs.getUri().getScheme());
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
@Test
|
|
@Test
|
|
@@ -108,7 +158,7 @@ public class TestOzoneFileInterfaces {
|
|
int stringLen = 20;
|
|
int stringLen = 20;
|
|
String data = RandomStringUtils.randomAlphanumeric(stringLen);
|
|
String data = RandomStringUtils.randomAlphanumeric(stringLen);
|
|
String filePath = RandomStringUtils.randomAlphanumeric(5);
|
|
String filePath = RandomStringUtils.randomAlphanumeric(5);
|
|
- Path path = new Path("/" + filePath);
|
|
|
|
|
|
+ Path path = createPath("/" + filePath);
|
|
try (FSDataOutputStream stream = fs.create(path)) {
|
|
try (FSDataOutputStream stream = fs.create(path)) {
|
|
stream.writeBytes(data);
|
|
stream.writeBytes(data);
|
|
}
|
|
}
|
|
@@ -116,28 +166,68 @@ public class TestOzoneFileInterfaces {
|
|
FileStatus status = fs.getFileStatus(path);
|
|
FileStatus status = fs.getFileStatus(path);
|
|
// The timestamp of the newly created file should always be greater than
|
|
// The timestamp of the newly created file should always be greater than
|
|
// the time when the test was started
|
|
// the time when the test was started
|
|
- Assert.assertTrue(status.getModificationTime() > currentTime);
|
|
|
|
|
|
+ assertTrue("Modification time has not been recorded: " + status,
|
|
|
|
+ status.getModificationTime() > currentTime);
|
|
|
|
|
|
try (FSDataInputStream inputStream = fs.open(path)) {
|
|
try (FSDataInputStream inputStream = fs.open(path)) {
|
|
byte[] buffer = new byte[stringLen];
|
|
byte[] buffer = new byte[stringLen];
|
|
inputStream.readFully(0, buffer);
|
|
inputStream.readFully(0, buffer);
|
|
String out = new String(buffer, 0, buffer.length);
|
|
String out = new String(buffer, 0, buffer.length);
|
|
- Assert.assertEquals(data, out);
|
|
|
|
|
|
+ assertEquals(data, out);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
@Test
|
|
@Test
|
|
public void testDirectory() throws IOException {
|
|
public void testDirectory() throws IOException {
|
|
String dirPath = RandomStringUtils.randomAlphanumeric(5);
|
|
String dirPath = RandomStringUtils.randomAlphanumeric(5);
|
|
- Path path = new Path("/" + dirPath);
|
|
|
|
- Assert.assertTrue(fs.mkdirs(path));
|
|
|
|
|
|
+ Path path = createPath("/" + dirPath);
|
|
|
|
+ assertTrue("Makedirs returned with false for the path " + path,
|
|
|
|
+ fs.mkdirs(path));
|
|
|
|
|
|
FileStatus status = fs.getFileStatus(path);
|
|
FileStatus status = fs.getFileStatus(path);
|
|
- Assert.assertTrue(status.isDirectory());
|
|
|
|
- Assert.assertEquals(0, status.getLen());
|
|
|
|
|
|
+ assertTrue("The created path is not directory.", status.isDirectory());
|
|
|
|
+
|
|
|
|
+ assertEquals(0, status.getLen());
|
|
|
|
+
|
|
|
|
+ FileStatus[] statusList = fs.listStatus(createPath("/"));
|
|
|
|
+ assertEquals(1, statusList.length);
|
|
|
|
+ assertEquals(status, statusList[0]);
|
|
|
|
+
|
|
|
|
+ FileStatus statusRoot = fs.getFileStatus(createPath("/"));
|
|
|
|
+ assertTrue("Root dir (/) is not a directory.", status.isDirectory());
|
|
|
|
+ assertEquals(0, status.getLen());
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
- FileStatus[] statusList = fs.listStatus(new Path("/"));
|
|
|
|
- Assert.assertEquals(1, statusList.length);
|
|
|
|
- Assert.assertEquals(status, statusList[0]);
|
|
|
|
|
|
+ @Test
|
|
|
|
+ public void testPathToKey() throws Exception {
|
|
|
|
+ OzoneFileSystem ozoneFs = (OzoneFileSystem) TestOzoneFileInterfaces.fs;
|
|
|
|
+
|
|
|
|
+ assertEquals("a/b/1", ozoneFs.pathToKey(new Path("/a/b/1")));
|
|
|
|
+
|
|
|
|
+ assertEquals("user/" + getCurrentUser() + "/key1/key2",
|
|
|
|
+ ozoneFs.pathToKey(new Path("key1/key2")));
|
|
|
|
+
|
|
|
|
+ assertEquals("key1/key2",
|
|
|
|
+ ozoneFs.pathToKey(new Path("o3://test1/key1/key2")));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String getCurrentUser() {
|
|
|
|
+ try {
|
|
|
|
+ return UserGroupInformation.getCurrentUser().getShortUserName();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ return OZONE_DEFAULT_USER;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Path createPath(String relativePath) {
|
|
|
|
+ if (useAbsolutePath) {
|
|
|
|
+ return new Path(
|
|
|
|
+ rootPath + (relativePath.startsWith("/") ? "" : "/") + relativePath);
|
|
|
|
+ } else {
|
|
|
|
+ return new Path(relativePath);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|