|
@@ -21,8 +21,8 @@ package org.apache.hadoop.fs.contract;
|
|
|
import org.apache.hadoop.fs.FSDataOutputStream;
|
|
|
import org.apache.hadoop.fs.FileAlreadyExistsException;
|
|
|
import org.apache.hadoop.fs.FileStatus;
|
|
|
+import org.apache.hadoop.fs.FileSystem;
|
|
|
import org.apache.hadoop.fs.Path;
|
|
|
-import org.apache.hadoop.io.IOUtils;
|
|
|
import org.junit.Test;
|
|
|
import org.junit.internal.AssumptionViolatedException;
|
|
|
|
|
@@ -30,16 +30,22 @@ import java.io.FileNotFoundException;
|
|
|
import java.io.IOException;
|
|
|
|
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.dataset;
|
|
|
+import static org.apache.hadoop.fs.contract.ContractTestUtils.getFileStatusEventually;
|
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.skip;
|
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.writeDataset;
|
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.writeTextFile;
|
|
|
|
|
|
/**
|
|
|
- * Test creating files, overwrite options &c
|
|
|
+ * Test creating files, overwrite options etc.
|
|
|
*/
|
|
|
public abstract class AbstractContractCreateTest extends
|
|
|
AbstractFSContractTestBase {
|
|
|
|
|
|
+ /**
|
|
|
+ * How long to wait for a path to become visible.
|
|
|
+ */
|
|
|
+ public static final int CREATE_TIMEOUT = 15000;
|
|
|
+
|
|
|
@Test
|
|
|
public void testCreateNewFile() throws Throwable {
|
|
|
describe("Foundational 'create a file' test");
|
|
@@ -180,4 +186,90 @@ public abstract class AbstractContractCreateTest extends
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testCreatedFileIsVisibleOnFlush() throws Throwable {
|
|
|
+ describe("verify that a newly created file exists once a flush has taken "
|
|
|
+ + "place");
|
|
|
+ Path path = path("testCreatedFileIsVisibleOnFlush");
|
|
|
+ FileSystem fs = getFileSystem();
|
|
|
+ try(FSDataOutputStream out = fs.create(path,
|
|
|
+ false,
|
|
|
+ 4096,
|
|
|
+ (short) 1,
|
|
|
+ 1024)) {
|
|
|
+ out.write('a');
|
|
|
+ out.flush();
|
|
|
+ if (!fs.exists(path)) {
|
|
|
+
|
|
|
+ if (isSupported(IS_BLOBSTORE)) {
|
|
|
+ // object store: downgrade to a skip so that the failure is visible
|
|
|
+ // in test results
|
|
|
+ skip("Filesystem is an object store and newly created files are not "
|
|
|
+ + "immediately visible");
|
|
|
+ }
|
|
|
+ assertPathExists("expected path to be visible before file closed",
|
|
|
+ path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testCreatedFileIsEventuallyVisible() throws Throwable {
|
|
|
+ describe("verify a written to file is visible after the stream is closed");
|
|
|
+ Path path = path("testCreatedFileIsEventuallyVisible");
|
|
|
+ FileSystem fs = getFileSystem();
|
|
|
+ try(
|
|
|
+ FSDataOutputStream out = fs.create(path,
|
|
|
+ false,
|
|
|
+ 4096,
|
|
|
+ (short) 1,
|
|
|
+ 1024)
|
|
|
+ ) {
|
|
|
+ out.write(0x01);
|
|
|
+ out.close();
|
|
|
+ getFileStatusEventually(fs, path, CREATE_TIMEOUT);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testFileStatusBlocksizeNonEmptyFile() throws Throwable {
|
|
|
+ describe("validate the block size of a filesystem and files within it");
|
|
|
+ FileSystem fs = getFileSystem();
|
|
|
+
|
|
|
+ long rootPath = fs.getDefaultBlockSize(path("/"));
|
|
|
+ assertTrue("Root block size is invalid " + rootPath,
|
|
|
+ rootPath > 0);
|
|
|
+
|
|
|
+ Path path = path("testFileStatusBlocksizeNonEmptyFile");
|
|
|
+ byte[] data = dataset(256, 'a', 'z');
|
|
|
+
|
|
|
+ writeDataset(fs, path, data, data.length, 1024 * 1024, false);
|
|
|
+
|
|
|
+ validateBlockSize(fs, path, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testFileStatusBlocksizeEmptyFile() throws Throwable {
|
|
|
+ describe("check that an empty file may return a 0-byte blocksize");
|
|
|
+ FileSystem fs = getFileSystem();
|
|
|
+ Path path = path("testFileStatusBlocksizeEmptyFile");
|
|
|
+ ContractTestUtils.touch(fs, path);
|
|
|
+ validateBlockSize(fs, path, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void validateBlockSize(FileSystem fs, Path path, int minValue)
|
|
|
+ throws IOException, InterruptedException {
|
|
|
+ FileStatus status =
|
|
|
+ getFileStatusEventually(fs, path, CREATE_TIMEOUT);
|
|
|
+ String statusDetails = status.toString();
|
|
|
+ assertTrue("File status block size too low: " + statusDetails
|
|
|
+ + " min value: " + minValue,
|
|
|
+ status.getBlockSize() >= minValue);
|
|
|
+ long defaultBlockSize = fs.getDefaultBlockSize(path);
|
|
|
+ assertTrue("fs.getDefaultBlockSize(" + path + ") size " +
|
|
|
+ defaultBlockSize + " is below the minimum of " + minValue,
|
|
|
+ defaultBlockSize >= minValue);
|
|
|
+ }
|
|
|
+
|
|
|
}
|