diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestRawLocalFileSystemContract.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestRawLocalFileSystemContract.java index 908e330b15f..2e514c4648e 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestRawLocalFileSystemContract.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestRawLocalFileSystemContract.java @@ -18,6 +18,8 @@ package org.apache.hadoop.fs; import java.io.File; +import java.io.IOException; +import java.util.regex.Pattern; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.test.GenericTestUtils; @@ -44,6 +46,18 @@ public class TestRawLocalFileSystemContract extends FileSystemContractBaseTest { private final static Path TEST_BASE_DIR = new Path(GenericTestUtils.getRandomizedTestDir().getAbsolutePath()); + // These are the string values that DF sees as "Filesystem" for a + // Docker container accessing a Mac or Windows host's filesystem. + private static final String FS_TYPE_MAC = "osxfs"; + private static boolean looksLikeMac(String filesys) { + return filesys.toLowerCase().contains(FS_TYPE_MAC.toLowerCase()); + } + private static final Pattern HAS_DRIVE_LETTER_SPECIFIER = + Pattern.compile("^/?[a-zA-Z]:"); + private static boolean looksLikeWindows(String filesys) { + return HAS_DRIVE_LETTER_SPECIFIER.matcher(filesys).find(); + } + @Before public void setUp() throws Exception { Configuration conf = new Configuration(); @@ -84,7 +98,29 @@ public class TestRawLocalFileSystemContract extends FileSystemContractBaseTest { @Override protected boolean filesystemIsCaseSensitive() { - return !(Shell.WINDOWS || Shell.MAC); + if (Shell.WINDOWS || Shell.MAC) { + return false; + } + // osType is linux or unix-like, but it might be in a container mounting a + // Mac or Windows volume. Use DF to try to determine if this is the case. + String rfsPathStr = "uninitialized"; + String rfsType; + try { + RawLocalFileSystem rfs = new RawLocalFileSystem(); + Configuration conf = new Configuration(); + rfs.initialize(rfs.getUri(), conf); + rfsPathStr = Path.getPathWithoutSchemeAndAuthority( + rfs.getWorkingDirectory()).toString(); + File rfsPath = new File(rfsPathStr); + // DF.getFilesystem() only provides indirect info about FS type, but it's + // the best we have. `df -T` would be better, but isn't cross-platform. + rfsType = (new DF(rfsPath, conf)).getFilesystem(); + LOG.info("DF.Filesystem is {} for path {}", rfsType, rfsPath); + } catch (IOException ex) { + LOG.error("DF failed on path {}", rfsPathStr); + rfsType = Shell.osType.toString(); + } + return !(looksLikeMac(rfsType) || looksLikeWindows(rfsType)); } // cross-check getPermission using both native/non-native @@ -107,8 +143,8 @@ public class TestRawLocalFileSystemContract extends FileSystemContractBaseTest { // test initial permission // RawLocalFileSystem.DeprecatedRawLocalFileStatus fsNIO = - new RawLocalFileSystem.DeprecatedRawLocalFileStatus( - file, defaultBlockSize, rfs); + new RawLocalFileSystem.DeprecatedRawLocalFileStatus( + file, defaultBlockSize, rfs); fsNIO.loadPermissionInfoByNativeIO(); RawLocalFileSystem.DeprecatedRawLocalFileStatus fsnonNIO = new RawLocalFileSystem.DeprecatedRawLocalFileStatus(