|
@@ -18,11 +18,7 @@
|
|
|
package org.apache.hadoop.util;
|
|
|
|
|
|
import java.io.*;
|
|
|
-import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
-import org.apache.hadoop.util.DiskChecker.FileIoProvider;
|
|
|
-import org.junit.After;
|
|
|
-import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
import static org.junit.Assert.*;
|
|
|
|
|
@@ -38,46 +34,27 @@ import org.apache.hadoop.fs.Path;
|
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
|
import org.apache.hadoop.util.DiskChecker.DiskErrorException;
|
|
|
import org.apache.hadoop.util.Shell;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
|
|
public class TestDiskChecker {
|
|
|
- public static final Logger LOG =
|
|
|
- LoggerFactory.getLogger(TestDiskChecker.class);
|
|
|
+ final FsPermission defaultPerm = new FsPermission("755");
|
|
|
+ final FsPermission invalidPerm = new FsPermission("000");
|
|
|
|
|
|
- private final FsPermission defaultPerm = new FsPermission("755");
|
|
|
- private final FsPermission invalidPerm = new FsPermission("000");
|
|
|
-
|
|
|
- private FileIoProvider fileIoProvider = null;
|
|
|
-
|
|
|
- @Before
|
|
|
- public void setup() {
|
|
|
- // Some tests replace the static field DiskChecker#fileIoProvider.
|
|
|
- // Cache it so we can restore it after each test completes.
|
|
|
- fileIoProvider = DiskChecker.getFileOutputStreamProvider();
|
|
|
- }
|
|
|
-
|
|
|
- @After
|
|
|
- public void cleanup() {
|
|
|
- DiskChecker.replaceFileOutputStreamProvider(fileIoProvider);
|
|
|
- }
|
|
|
-
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testMkdirs_dirExists() throws Throwable {
|
|
|
_mkdirs(true, defaultPerm, defaultPerm);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testMkdirs_noDir() throws Throwable {
|
|
|
_mkdirs(false, defaultPerm, defaultPerm);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testMkdirs_dirExists_badUmask() throws Throwable {
|
|
|
_mkdirs(true, defaultPerm, invalidPerm);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testMkdirs_noDir_badUmask() throws Throwable {
|
|
|
_mkdirs(false, defaultPerm, invalidPerm);
|
|
|
}
|
|
@@ -102,33 +79,34 @@ public class TestDiskChecker {
|
|
|
verify(fs).getFileStatus(dir);
|
|
|
verify(stat).getPermission();
|
|
|
}
|
|
|
- } catch (DiskErrorException e) {
|
|
|
+ }
|
|
|
+ catch (DiskErrorException e) {
|
|
|
if (before != after)
|
|
|
assertTrue(e.getMessage().startsWith("Incorrect permission"));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_normal() throws Throwable {
|
|
|
_checkDirs(true, new FsPermission("755"), true);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notDir() throws Throwable {
|
|
|
_checkDirs(false, new FsPermission("000"), false);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notReadable() throws Throwable {
|
|
|
_checkDirs(true, new FsPermission("000"), false);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notWritable() throws Throwable {
|
|
|
_checkDirs(true, new FsPermission("444"), false);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notListable() throws Throwable {
|
|
|
_checkDirs(true, new FsPermission("666"), false); // not listable
|
|
|
}
|
|
@@ -141,15 +119,13 @@ public class TestDiskChecker {
|
|
|
localDir.mkdir();
|
|
|
}
|
|
|
Shell.execCommand(Shell.getSetPermissionCommand(String.format("%04o",
|
|
|
- perm.toShort()), false, localDir.getAbsolutePath()));
|
|
|
+ perm.toShort()), false, localDir.getAbsolutePath()));
|
|
|
try {
|
|
|
DiskChecker.checkDir(FileSystem.getLocal(new Configuration()),
|
|
|
- new Path(localDir.getAbsolutePath()), perm);
|
|
|
- assertTrue("checkDir success, expected failure", success);
|
|
|
+ new Path(localDir.getAbsolutePath()), perm);
|
|
|
+ assertTrue("checkDir success", success);
|
|
|
} catch (DiskErrorException e) {
|
|
|
- if (success) {
|
|
|
- throw e; // Unexpected exception!
|
|
|
- }
|
|
|
+ assertFalse("checkDir success", success);
|
|
|
}
|
|
|
localDir.delete();
|
|
|
}
|
|
@@ -159,27 +135,27 @@ public class TestDiskChecker {
|
|
|
* permission for result of mapper.
|
|
|
*/
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_normal_local() throws Throwable {
|
|
|
_checkDirs(true, "755", true);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notDir_local() throws Throwable {
|
|
|
_checkDirs(false, "000", false);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notReadable_local() throws Throwable {
|
|
|
_checkDirs(true, "000", false);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notWritable_local() throws Throwable {
|
|
|
_checkDirs(true, "444", false);
|
|
|
}
|
|
|
|
|
|
- @Test(timeout = 30000)
|
|
|
+ @Test (timeout = 30000)
|
|
|
public void testCheckDir_notListable_local() throws Throwable {
|
|
|
_checkDirs(true, "666", false);
|
|
|
}
|
|
@@ -192,116 +168,16 @@ public class TestDiskChecker {
|
|
|
localDir.mkdir();
|
|
|
}
|
|
|
Shell.execCommand(Shell.getSetPermissionCommand(perm, false,
|
|
|
- localDir.getAbsolutePath()));
|
|
|
+ localDir.getAbsolutePath()));
|
|
|
try {
|
|
|
DiskChecker.checkDir(localDir);
|
|
|
- assertTrue("checkDir success, expected failure", success);
|
|
|
+ assertTrue("checkDir success", success);
|
|
|
} catch (DiskErrorException e) {
|
|
|
- if (success) {
|
|
|
- throw e; // Unexpected exception!
|
|
|
- }
|
|
|
+ e.printStackTrace();
|
|
|
+ assertFalse("checkDir success", success);
|
|
|
}
|
|
|
localDir.delete();
|
|
|
- }
|
|
|
+ System.out.println("checkDir success: " + success);
|
|
|
|
|
|
- /**
|
|
|
- * Verify DiskChecker ignores at least 2 transient file creation errors.
|
|
|
- */
|
|
|
- @Test(timeout = 30000)
|
|
|
- public void testDiskIoIgnoresTransientCreateErrors() throws Throwable {
|
|
|
- DiskChecker.replaceFileOutputStreamProvider(new TestFileIoProvider(
|
|
|
- DiskChecker.DISK_IO_MAX_ITERATIONS - 1, 0));
|
|
|
- _checkDirs(true, "755", true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Verify DiskChecker bails after 3 file creation errors.
|
|
|
- */
|
|
|
- @Test(timeout = 30000)
|
|
|
- public void testDiskIoDetectsCreateErrors() throws Throwable {
|
|
|
- DiskChecker.replaceFileOutputStreamProvider(new TestFileIoProvider(
|
|
|
- DiskChecker.DISK_IO_MAX_ITERATIONS, 0));
|
|
|
- _checkDirs(true, "755", false);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Verify DiskChecker ignores at least 2 transient file write errors.
|
|
|
- */
|
|
|
- @Test(timeout = 30000)
|
|
|
- public void testDiskIoIgnoresTransientWriteErrors() throws Throwable {
|
|
|
- DiskChecker.replaceFileOutputStreamProvider(new TestFileIoProvider(
|
|
|
- 0, DiskChecker.DISK_IO_MAX_ITERATIONS - 1));
|
|
|
- _checkDirs(true, "755", true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Verify DiskChecker bails after 3 file write errors.
|
|
|
- */
|
|
|
- @Test(timeout = 30000)
|
|
|
- public void testDiskIoDetectsWriteErrors() throws Throwable {
|
|
|
- DiskChecker.replaceFileOutputStreamProvider(new TestFileIoProvider(
|
|
|
- 0, DiskChecker.DISK_IO_MAX_ITERATIONS));
|
|
|
- _checkDirs(true, "755", false);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Verify DiskChecker's test file naming scheme.
|
|
|
- */
|
|
|
- @Test(timeout = 30000)
|
|
|
- public void testDiskIoFileNaming() throws Throwable {
|
|
|
- final File rootDir = new File("/");
|
|
|
- assertTrue(".001".matches("\\.00\\d$"));
|
|
|
- for (int i = 1; i < DiskChecker.DISK_IO_MAX_ITERATIONS; ++i) {
|
|
|
- final File file = DiskChecker.getFileNameForDiskIoCheck(rootDir, i);
|
|
|
- assertTrue(
|
|
|
- "File name does not match expected pattern: " + file,
|
|
|
- file.toString().matches("^.*\\.[0-9]+$"));
|
|
|
- }
|
|
|
- final File guidFile = DiskChecker.getFileNameForDiskIoCheck(
|
|
|
- rootDir, DiskChecker.DISK_IO_MAX_ITERATIONS);
|
|
|
- assertTrue(
|
|
|
- "File name does not match expected pattern: " + guidFile,
|
|
|
- guidFile.toString().matches("^.*\\.[A-Za-z0-9-]+$"));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * A dummy {@link DiskChecker.FileIoProvider} that can throw a programmable
|
|
|
- * number of times.
|
|
|
- */
|
|
|
- private static class TestFileIoProvider implements FileIoProvider {
|
|
|
- private final AtomicInteger numCreateCalls = new AtomicInteger(0);
|
|
|
- private final AtomicInteger numWriteCalls = new AtomicInteger(0);
|
|
|
-
|
|
|
- private final int numTimesToThrowOnCreate;
|
|
|
- private final int numTimesToThrowOnWrite;
|
|
|
-
|
|
|
- public TestFileIoProvider(
|
|
|
- int numTimesToThrowOnCreate, int numTimesToThrowOnWrite) {
|
|
|
- this.numTimesToThrowOnCreate = numTimesToThrowOnCreate;
|
|
|
- this.numTimesToThrowOnWrite = numTimesToThrowOnWrite;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- @Override
|
|
|
- public FileOutputStream get(File f) throws FileNotFoundException {
|
|
|
- if (numCreateCalls.getAndIncrement() < numTimesToThrowOnCreate) {
|
|
|
- throw new FileNotFoundException("Dummy exception for testing");
|
|
|
- }
|
|
|
- // Can't mock final class FileOutputStream.
|
|
|
- return new FileOutputStream(f);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * {@inheritDoc}
|
|
|
- */
|
|
|
- @Override
|
|
|
- public void write(FileOutputStream fos, byte[] data) throws IOException {
|
|
|
- if (numWriteCalls.getAndIncrement() < numTimesToThrowOnWrite) {
|
|
|
- throw new IOException("Dummy exception for testing");
|
|
|
- }
|
|
|
- fos.write(data);
|
|
|
- }
|
|
|
}
|
|
|
}
|