| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.fs; |
| |
| import static org.junit.Assert.*; |
| |
| import java.io.IOException; |
| import java.security.PrivilegedExceptionAction; |
| import java.util.ArrayList; |
| import java.util.UUID; |
| import java.util.regex.Pattern; |
| |
| import com.google.common.collect.Ordering; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.permission.FsPermission; |
| import org.apache.hadoop.hdfs.HdfsConfiguration; |
| import org.apache.hadoop.hdfs.MiniDFSCluster; |
| import org.apache.hadoop.hdfs.server.namenode.INodeId; |
| import org.apache.hadoop.security.AccessControlException; |
| import org.apache.hadoop.security.UserGroupInformation; |
| import org.junit.*; |
| |
| public class TestGlobPaths { |
| |
| private static final UserGroupInformation unprivilegedUser = |
| UserGroupInformation.createUserForTesting("myuser", |
| new String[] { "mygroup" }); |
| |
| static class RegexPathFilter implements PathFilter { |
| |
| private final String regex; |
| public RegexPathFilter(String regex) { |
| this.regex = regex; |
| } |
| |
| @Override |
| public boolean accept(Path path) { |
| return path.toString().matches(regex); |
| } |
| |
| } |
| |
| static private MiniDFSCluster dfsCluster; |
| static private FileSystem fs; |
| static private FileSystem privilegedFs; |
| static private FileContext fc; |
| static private FileContext privilegedFc; |
| static final private int NUM_OF_PATHS = 4; |
| static private String USER_DIR; |
| private final Path[] path = new Path[NUM_OF_PATHS]; |
| |
| @BeforeClass |
| public static void setUp() throws Exception { |
| final Configuration conf = new HdfsConfiguration(); |
| dfsCluster = new MiniDFSCluster.Builder(conf).build(); |
| |
| privilegedFs = FileSystem.get(conf); |
| privilegedFc = FileContext.getFileContext(conf); |
| // allow unpriviledged user ability to create paths |
| privilegedFs.setPermission(new Path("/"), |
| FsPermission.createImmutable((short)0777)); |
| UserGroupInformation.setLoginUser(unprivilegedUser); |
| fs = FileSystem.get(conf); |
| fc = FileContext.getFileContext(conf); |
| USER_DIR = fs.getHomeDirectory().toUri().getPath().toString(); |
| } |
| |
| @AfterClass |
| public static void tearDown() throws Exception { |
| if(dfsCluster!=null) { |
| dfsCluster.shutdown(); |
| } |
| } |
| |
| @Test |
| public void testMultiGlob() throws IOException { |
| FileStatus[] status; |
| /* |
| * /dir1/subdir1 |
| * /dir1/subdir1/f1 |
| * /dir1/subdir1/f2 |
| * /dir1/subdir2/f1 |
| * /dir2/subdir1 |
| * /dir2/subdir2 |
| * /dir2/subdir2/f1 |
| * /dir3/f1 |
| * /dir3/f1 |
| * /dir3/f2(dir) |
| * /dir3/subdir2(file) |
| * /dir3/subdir3 |
| * /dir3/subdir3/f1 |
| * /dir3/subdir3/f1/f1 |
| * /dir3/subdir3/f3 |
| * /dir4 |
| */ |
| |
| Path d1 = new Path(USER_DIR, "dir1"); |
| Path d11 = new Path(d1, "subdir1"); |
| Path d12 = new Path(d1, "subdir2"); |
| |
| Path f111 = new Path(d11, "f1"); |
| fs.createNewFile(f111); |
| Path f112 = new Path(d11, "f2"); |
| fs.createNewFile(f112); |
| Path f121 = new Path(d12, "f1"); |
| fs.createNewFile(f121); |
| |
| Path d2 = new Path(USER_DIR, "dir2"); |
| Path d21 = new Path(d2, "subdir1"); |
| fs.mkdirs(d21); |
| Path d22 = new Path(d2, "subdir2"); |
| Path f221 = new Path(d22, "f1"); |
| fs.createNewFile(f221); |
| |
| Path d3 = new Path(USER_DIR, "dir3"); |
| Path f31 = new Path(d3, "f1"); |
| fs.createNewFile(f31); |
| Path d32 = new Path(d3, "f2"); |
| fs.mkdirs(d32); |
| Path f32 = new Path(d3, "subdir2"); // fake as a subdir! |
| fs.createNewFile(f32); |
| Path d33 = new Path(d3, "subdir3"); |
| Path f333 = new Path(d33, "f3"); |
| fs.createNewFile(f333); |
| Path d331 = new Path(d33, "f1"); |
| Path f3311 = new Path(d331, "f1"); |
| fs.createNewFile(f3311); |
| Path d4 = new Path(USER_DIR, "dir4"); |
| fs.mkdirs(d4); |
| |
| /* |
| * basic |
| */ |
| Path root = new Path(USER_DIR); |
| status = fs.globStatus(root); |
| checkStatus(status, root); |
| |
| status = fs.globStatus(new Path(USER_DIR, "x")); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path("x")); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "x/x")); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path("x/x")); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "*")); |
| checkStatus(status, d1, d2, d3, d4); |
| |
| status = fs.globStatus(new Path("*")); |
| checkStatus(status, d1, d2, d3, d4); |
| |
| status = fs.globStatus(new Path(USER_DIR, "*/x")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("*/x")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "x/*")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("x/*")); |
| checkStatus(status); |
| |
| // make sure full pattern is scanned instead of bailing early with undef |
| status = fs.globStatus(new Path(USER_DIR, "x/x/x/*")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("x/x/x/*")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "*/*")); |
| checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33); |
| |
| status = fs.globStatus(new Path("*/*")); |
| checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33); |
| |
| /* |
| * one level deep |
| */ |
| status = fs.globStatus(new Path(USER_DIR, "dir*/*")); |
| checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33); |
| |
| status = fs.globStatus(new Path("dir*/*")); |
| checkStatus(status, d11, d12, d21, d22, f31, d32, f32, d33); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*")); |
| checkStatus(status, d11, d12, d21, d22, f32, d33); |
| |
| status = fs.globStatus(new Path("dir*/subdir*")); |
| checkStatus(status, d11, d12, d21, d22, f32, d33); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/f*")); |
| checkStatus(status, f31, d32); |
| |
| status = fs.globStatus(new Path("dir*/f*")); |
| checkStatus(status, f31, d32); |
| |
| /* |
| * subdir1 globs |
| */ |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1")); |
| checkStatus(status, d11, d21); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/*")); |
| checkStatus(status, f111, f112); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/*/*")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/x")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/x*")); |
| checkStatus(status); |
| |
| /* |
| * subdir2 globs |
| */ |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir2")); |
| checkStatus(status, d12, d22, f32); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir2/*")); |
| checkStatus(status, f121, f221); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir2/*/*")); |
| checkStatus(status); |
| |
| /* |
| * subdir3 globs |
| */ |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3")); |
| checkStatus(status, d33); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3/*")); |
| checkStatus(status, d331, f333); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3/*/*")); |
| checkStatus(status, f3311); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir3/*/*/*")); |
| checkStatus(status); |
| |
| /* |
| * file1 single dir globs |
| */ |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1")); |
| checkStatus(status, f111); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1*")); |
| checkStatus(status, f111); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1/*")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f1*/*")); |
| checkStatus(status); |
| |
| /* |
| * file1 multi-dir globs |
| */ |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1")); |
| checkStatus(status, f111, f121, f221, d331); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*")); |
| checkStatus(status, f111, f121, f221, d331); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1/*")); |
| checkStatus(status, f3311); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/*")); |
| checkStatus(status, f3311); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/*")); |
| checkStatus(status, f3311); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/x")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f1*/*/*")); |
| checkStatus(status); |
| |
| /* |
| * file glob multiple files |
| */ |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*")); |
| checkStatus(status, d11, d12, d21, d22, f32, d33); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/*")); |
| checkStatus(status, f111, f112, f121, f221, d331, f333); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f*")); |
| checkStatus(status, f111, f112, f121, f221, d331, f333); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/f*/*")); |
| checkStatus(status, f3311); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/*/f1")); |
| checkStatus(status, f3311); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir*/*/*")); |
| checkStatus(status, f3311); |
| |
| |
| // doesn't exist |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f3")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "dir*/subdir1/f3*")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("{x}")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("{x,y}")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("dir*/{x,y}")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("dir*/{f1,y}")); |
| checkStatus(status, f31); |
| |
| status = fs.globStatus(new Path("{x,y}")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("/{x/x,y/y}")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("{x/x,y/y}")); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path(Path.CUR_DIR)); |
| checkStatus(status, new Path(USER_DIR)); |
| |
| status = fs.globStatus(new Path(USER_DIR+"{/dir1}")); |
| checkStatus(status, d1); |
| |
| status = fs.globStatus(new Path(USER_DIR+"{/dir*}")); |
| checkStatus(status, d1, d2, d3, d4); |
| |
| status = fs.globStatus(new Path(Path.SEPARATOR), trueFilter); |
| checkStatus(status, new Path(Path.SEPARATOR)); |
| |
| status = fs.globStatus(new Path(Path.CUR_DIR), trueFilter); |
| checkStatus(status, new Path(USER_DIR)); |
| |
| status = fs.globStatus(d1, trueFilter); |
| checkStatus(status, d1); |
| |
| status = fs.globStatus(new Path(USER_DIR), trueFilter); |
| checkStatus(status, new Path(USER_DIR)); |
| |
| status = fs.globStatus(new Path(USER_DIR, "*"), trueFilter); |
| checkStatus(status, d1, d2, d3, d4); |
| |
| status = fs.globStatus(new Path("/x/*"), trueFilter); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("/x"), trueFilter); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path("/x/x"), trueFilter); |
| assertNull(status); |
| |
| /* |
| * false filter |
| */ |
| PathFilter falseFilter = new PathFilter() { |
| @Override |
| public boolean accept(Path path) { |
| return false; |
| } |
| }; |
| |
| status = fs.globStatus(new Path(Path.SEPARATOR), falseFilter); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path(Path.CUR_DIR), falseFilter); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path(USER_DIR), falseFilter); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path(USER_DIR, "*"), falseFilter); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("/x/*"), falseFilter); |
| checkStatus(status); |
| |
| status = fs.globStatus(new Path("/x"), falseFilter); |
| assertNull(status); |
| |
| status = fs.globStatus(new Path("/x/x"), falseFilter); |
| assertNull(status); |
| |
| cleanupDFS(); |
| } |
| |
| private void checkStatus(FileStatus[] status, Path ... expectedMatches) { |
| assertNotNull(status); |
| String[] paths = new String[status.length]; |
| for (int i=0; i < status.length; i++) { |
| paths[i] = getPathFromStatus(status[i]); |
| } |
| String got = StringUtils.join(paths, "\n"); |
| String expected = StringUtils.join(expectedMatches, "\n"); |
| assertEquals(expected, got); |
| } |
| |
| private String getPathFromStatus(FileStatus status) { |
| return status.getPath().toUri().getPath(); |
| } |
| |
| |
| @Test |
| public void testPathFilter() throws IOException { |
| try { |
| String[] files = new String[] { USER_DIR + "/a", USER_DIR + "/a/b" }; |
| Path[] matchedPath = prepareTesting(USER_DIR + "/*/*", files, |
| new RegexPathFilter("^.*" + Pattern.quote(USER_DIR) + "/a/b")); |
| assertEquals(1, matchedPath.length); |
| assertEquals(path[1], matchedPath[0]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void testPathFilterWithFixedLastComponent() throws IOException { |
| try { |
| String[] files = new String[] { USER_DIR + "/a", USER_DIR + "/a/b", |
| USER_DIR + "/c", USER_DIR + "/c/b", }; |
| Path[] matchedPath = prepareTesting(USER_DIR + "/*/b", files, |
| new RegexPathFilter("^.*" + Pattern.quote(USER_DIR) + "/a/b")); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[1]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestLiteral() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/a2c", USER_DIR+"/abc.d"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/abc.d", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[1]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestEscape() throws IOException { |
| // Skip the test case on Windows because backslash will be treated as a |
| // path separator instead of an escaping character on Windows. |
| org.junit.Assume.assumeTrue(!Path.WINDOWS); |
| try { |
| String [] files = new String[] {USER_DIR+"/ab\\[c.d"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/ab\\[c.d", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[0]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestAny() throws IOException { |
| try { |
| String [] files = new String[] { USER_DIR+"/abc", USER_DIR+"/a2c", |
| USER_DIR+"/a.c", USER_DIR+"/abcd"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/a?c", files); |
| assertEquals(matchedPath.length, 3); |
| assertEquals(matchedPath[0], path[2]); |
| assertEquals(matchedPath[1], path[1]); |
| assertEquals(matchedPath[2], path[0]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestClosure1() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/a", USER_DIR+"/abc", |
| USER_DIR+"/abc.p", USER_DIR+"/bacd"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/a*", files); |
| assertEquals(matchedPath.length, 3); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[1]); |
| assertEquals(matchedPath[2], path[2]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestClosure2() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/a.", USER_DIR+"/a.txt", |
| USER_DIR+"/a.old.java", USER_DIR+"/.java"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/a.*", files); |
| assertEquals(matchedPath.length, 3); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[2]); |
| assertEquals(matchedPath[2], path[1]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestClosure3() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/a.txt.x", USER_DIR+"/ax", |
| USER_DIR+"/ab37x", USER_DIR+"/bacd"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/a*x", files); |
| assertEquals(matchedPath.length, 3); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[2]); |
| assertEquals(matchedPath[2], path[1]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestClosure4() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/dir1/file1", |
| USER_DIR+"/dir2/file2", |
| USER_DIR+"/dir3/file1"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/*/file1", files); |
| assertEquals(matchedPath.length, 2); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[2]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestClosure5() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/dir1/file1", |
| USER_DIR+"/file1"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/*/file1", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[0]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestSet() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/a.c", USER_DIR+"/a.cpp", |
| USER_DIR+"/a.hlp", USER_DIR+"/a.hxy"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/a.[ch]??", files); |
| assertEquals(matchedPath.length, 3); |
| assertEquals(matchedPath[0], path[1]); |
| assertEquals(matchedPath[1], path[2]); |
| assertEquals(matchedPath[2], path[3]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestRange() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/a.d", USER_DIR+"/a.e", |
| USER_DIR+"/a.f", USER_DIR+"/a.h"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/a.[d-fm]", files); |
| assertEquals(matchedPath.length, 3); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[1]); |
| assertEquals(matchedPath[2], path[2]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestSetExcl() throws IOException { |
| try { |
| String [] files = new String[] {USER_DIR+"/a.d", USER_DIR+"/a.e", |
| USER_DIR+"/a.0", USER_DIR+"/a.h"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/a.[^a-cg-z0-9]", files); |
| assertEquals(matchedPath.length, 2); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[1]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| @Test |
| public void pTestCombination() throws IOException { |
| try { |
| String [] files = new String[] {"/user/aa/a.c", "/user/bb/a.cpp", |
| "/user1/cc/b.hlp", "/user/dd/a.hxy"}; |
| Path[] matchedPath = prepareTesting("/use?/*/a.[ch]{lp,xy}", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[3]); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| /* Test {xx,yy} */ |
| @Test |
| public void pTestCurlyBracket() throws IOException { |
| Path[] matchedPath; |
| String [] files; |
| try { |
| files = new String[] { USER_DIR+"/a.abcxx", USER_DIR+"/a.abxy", |
| USER_DIR+"/a.hlp", USER_DIR+"/a.jhyy"}; |
| matchedPath = prepareTesting(USER_DIR+"/a.{abc,jh}??", files); |
| assertEquals(matchedPath.length, 2); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[3]); |
| } finally { |
| cleanupDFS(); |
| } |
| // nested curlies |
| try { |
| files = new String[] { USER_DIR+"/a.abcxx", USER_DIR+"/a.abdxy", |
| USER_DIR+"/a.hlp", USER_DIR+"/a.jhyy" }; |
| matchedPath = prepareTesting(USER_DIR+"/a.{ab{c,d},jh}??", files); |
| assertEquals(matchedPath.length, 3); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[1]); |
| assertEquals(matchedPath[2], path[3]); |
| } finally { |
| cleanupDFS(); |
| } |
| // cross-component curlies |
| try { |
| files = new String[] { USER_DIR+"/a/b", USER_DIR+"/a/d", |
| USER_DIR+"/c/b", USER_DIR+"/c/d" }; |
| matchedPath = prepareTesting(USER_DIR+"/{a/b,c/d}", files); |
| assertEquals(matchedPath.length, 2); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[3]); |
| } finally { |
| cleanupDFS(); |
| } |
| // cross-component absolute curlies |
| try { |
| files = new String[] { "/a/b", "/a/d", |
| "/c/b", "/c/d" }; |
| matchedPath = prepareTesting("{/a/b,/c/d}", files); |
| assertEquals(matchedPath.length, 2); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[3]); |
| } finally { |
| cleanupDFS(); |
| } |
| try { |
| // test standalone } |
| files = new String[] {USER_DIR+"/}bc", USER_DIR+"/}c"}; |
| matchedPath = prepareTesting(USER_DIR+"/}{a,b}c", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[0]); |
| // test {b} |
| matchedPath = prepareTesting(USER_DIR+"/}{b}c", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[0]); |
| // test {} |
| matchedPath = prepareTesting(USER_DIR+"/}{}bc", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[0]); |
| |
| // test {,} |
| matchedPath = prepareTesting(USER_DIR+"/}{,}bc", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[0]); |
| |
| // test {b,} |
| matchedPath = prepareTesting(USER_DIR+"/}{b,}c", files); |
| assertEquals(matchedPath.length, 2); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[1]); |
| |
| // test {,b} |
| matchedPath = prepareTesting(USER_DIR+"/}{,b}c", files); |
| assertEquals(matchedPath.length, 2); |
| assertEquals(matchedPath[0], path[0]); |
| assertEquals(matchedPath[1], path[1]); |
| |
| // test a combination of {} and ? |
| matchedPath = prepareTesting(USER_DIR+"/}{ac,?}", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[1]); |
| |
| // test ill-formed curly |
| boolean hasException = false; |
| try { |
| prepareTesting(USER_DIR+"}{bc", files); |
| } catch (IOException e) { |
| assertTrue(e.getMessage().startsWith("Illegal file pattern:") ); |
| hasException = true; |
| } |
| assertTrue(hasException); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| /* test that a path name can contain Java regex special characters */ |
| @Test |
| public void pTestJavaRegexSpecialChars() throws IOException { |
| try { |
| String[] files = new String[] {USER_DIR+"/($.|+)bc", USER_DIR+"/abc"}; |
| Path[] matchedPath = prepareTesting(USER_DIR+"/($.|+)*", files); |
| assertEquals(matchedPath.length, 1); |
| assertEquals(matchedPath[0], path[0]); |
| } finally { |
| cleanupDFS(); |
| } |
| |
| } |
| |
| private Path[] prepareTesting(String pattern, String[] files) |
| throws IOException { |
| for(int i=0; i<Math.min(NUM_OF_PATHS, files.length); i++) { |
| path[i] = fs.makeQualified(new Path(files[i])); |
| if (!fs.mkdirs(path[i])) { |
| throw new IOException("Mkdirs failed to create " + path[i].toString()); |
| } |
| } |
| Path patternPath = new Path(pattern); |
| Path[] globResults = FileUtil.stat2Paths(fs.globStatus(patternPath), |
| patternPath); |
| for(int i=0; i<globResults.length; i++) { |
| globResults[i] = |
| globResults[i].makeQualified(fs.getUri(), fs.getWorkingDirectory()); |
| } |
| return globResults; |
| } |
| |
| private Path[] prepareTesting(String pattern, String[] files, |
| PathFilter filter) throws IOException { |
| for(int i=0; i<Math.min(NUM_OF_PATHS, files.length); i++) { |
| path[i] = fs.makeQualified(new Path(files[i])); |
| if (!fs.mkdirs(path[i])) { |
| throw new IOException("Mkdirs failed to create " + path[i].toString()); |
| } |
| } |
| Path patternPath = new Path(pattern); |
| Path[] globResults = FileUtil.stat2Paths(fs.globStatus(patternPath, filter), |
| patternPath); |
| for(int i=0; i<globResults.length; i++) { |
| globResults[i] = |
| globResults[i].makeQualified(fs.getUri(), fs.getWorkingDirectory()); |
| } |
| return globResults; |
| } |
| |
| private void cleanupDFS() throws IOException { |
| fs.delete(new Path(USER_DIR), true); |
| } |
| |
| /** |
| * A glob test that can be run on either FileContext or FileSystem. |
| */ |
| private abstract class FSTestWrapperGlobTest { |
| FSTestWrapperGlobTest(boolean useFc) { |
| if (useFc) { |
| this.privWrap = new FileContextTestWrapper(privilegedFc); |
| this.wrap = new FileContextTestWrapper(fc); |
| } else { |
| this.privWrap = new FileSystemTestWrapper(privilegedFs); |
| this.wrap = new FileSystemTestWrapper(fs); |
| } |
| } |
| |
| abstract void run() throws Exception; |
| |
| final FSTestWrapper privWrap; |
| final FSTestWrapper wrap; |
| } |
| |
| /** |
| * Run a glob test on FileSystem. |
| */ |
| private void testOnFileSystem(FSTestWrapperGlobTest test) throws Exception { |
| try { |
| fc.mkdir(new Path(USER_DIR), FsPermission.getDefault(), true); |
| test.run(); |
| } finally { |
| fc.delete(new Path(USER_DIR), true); |
| } |
| } |
| |
| /** |
| * Run a glob test on FileContext. |
| */ |
| private void testOnFileContext(FSTestWrapperGlobTest test) throws Exception { |
| try { |
| fs.mkdirs(new Path(USER_DIR)); |
| test.run(); |
| } finally { |
| cleanupDFS(); |
| } |
| } |
| |
| /** |
| * Accept all paths. |
| */ |
| private static class AcceptAllPathFilter implements PathFilter { |
| @Override |
| public boolean accept(Path path) { |
| return true; |
| } |
| } |
| |
| private static final PathFilter trueFilter = new AcceptAllPathFilter(); |
| |
| /** |
| * Accept only paths ending in Z. |
| */ |
| private static class AcceptPathsEndingInZ implements PathFilter { |
| @Override |
| public boolean accept(Path path) { |
| String stringPath = path.toUri().getPath(); |
| return stringPath.endsWith("z"); |
| } |
| } |
| |
| /** |
| * Test globbing through symlinks. |
| */ |
| private class TestGlobWithSymlinks extends FSTestWrapperGlobTest { |
| TestGlobWithSymlinks(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| // Test that globbing through a symlink to a directory yields a path |
| // containing that symlink. |
| wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(), |
| false); |
| wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR |
| + "/alphaLink"), false); |
| wrap.mkdir(new Path(USER_DIR + "/alphaLink/beta"), |
| FsPermission.getDirDefault(), false); |
| // Test simple glob |
| FileStatus[] statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/*"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals(USER_DIR + "/alpha/beta", statuses[0].getPath() |
| .toUri().getPath()); |
| // Test glob through symlink |
| statuses = wrap.globStatus(new Path(USER_DIR + "/alphaLink/*"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals(USER_DIR + "/alphaLink/beta", statuses[0].getPath() |
| .toUri().getPath()); |
| // If the terminal path component in a globbed path is a symlink, |
| // we don't dereference that link. |
| wrap.createSymlink(new Path("beta"), new Path(USER_DIR |
| + "/alphaLink/betaLink"), false); |
| statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/betaLi*"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals(USER_DIR + "/alpha/betaLink", statuses[0].getPath() |
| .toUri().getPath()); |
| // todo: test symlink-to-symlink-to-dir, etc. |
| } |
| } |
| |
| @Ignore |
| @Test |
| public void testGlobWithSymlinksOnFS() throws Exception { |
| testOnFileSystem(new TestGlobWithSymlinks(false)); |
| } |
| |
| @Ignore |
| @Test |
| public void testGlobWithSymlinksOnFC() throws Exception { |
| testOnFileContext(new TestGlobWithSymlinks(true)); |
| } |
| |
| /** |
| * Test globbing symlinks to symlinks. |
| * |
| * Also test globbing dangling symlinks. It should NOT throw any exceptions! |
| */ |
| private class TestGlobWithSymlinksToSymlinks extends |
| FSTestWrapperGlobTest { |
| TestGlobWithSymlinksToSymlinks(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| // Test that globbing through a symlink to a symlink to a directory |
| // fully resolves |
| wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(), |
| false); |
| wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR |
| + "/alphaLink"), false); |
| wrap.createSymlink(new Path(USER_DIR + "/alphaLink"), new Path(USER_DIR |
| + "/alphaLinkLink"), false); |
| wrap.mkdir(new Path(USER_DIR + "/alpha/beta"), |
| FsPermission.getDirDefault(), false); |
| // Test glob through symlink to a symlink to a directory |
| FileStatus statuses[] = wrap.globStatus(new Path(USER_DIR |
| + "/alphaLinkLink"), new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals(USER_DIR + "/alphaLinkLink", statuses[0].getPath() |
| .toUri().getPath()); |
| statuses = wrap.globStatus(new Path(USER_DIR + "/alphaLinkLink/*"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals(USER_DIR + "/alphaLinkLink/beta", statuses[0] |
| .getPath().toUri().getPath()); |
| // Test glob of dangling symlink (theta does not actually exist) |
| wrap.createSymlink(new Path(USER_DIR + "theta"), new Path(USER_DIR |
| + "/alpha/kappa"), false); |
| statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/kappa/kappa"), |
| new AcceptAllPathFilter()); |
| Assert.assertNull(statuses); |
| // Test glob of symlinks |
| wrap.createFile(USER_DIR + "/alpha/beta/gamma"); |
| wrap.createSymlink(new Path(USER_DIR + "gamma"), new Path(USER_DIR |
| + "/alpha/beta/gammaLink"), false); |
| wrap.createSymlink(new Path(USER_DIR + "gammaLink"), new Path(USER_DIR |
| + "/alpha/beta/gammaLinkLink"), false); |
| wrap.createSymlink(new Path(USER_DIR + "gammaLinkLink"), new Path( |
| USER_DIR + "/alpha/beta/gammaLinkLinkLink"), false); |
| statuses = wrap.globStatus(new Path(USER_DIR |
| + "/alpha/*/gammaLinkLinkLink"), new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals(USER_DIR + "/alpha/beta/gammaLinkLinkLink", |
| statuses[0].getPath().toUri().getPath()); |
| statuses = wrap.globStatus(new Path(USER_DIR + "/alpha/beta/*"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(USER_DIR + "/alpha/beta/gamma;" + USER_DIR |
| + "/alpha/beta/gammaLink;" + USER_DIR + "/alpha/beta/gammaLinkLink;" |
| + USER_DIR + "/alpha/beta/gammaLinkLinkLink", |
| TestPath.mergeStatuses(statuses)); |
| // Let's create two symlinks that point to each other, and glob on them. |
| wrap.createSymlink(new Path(USER_DIR + "tweedledee"), new Path(USER_DIR |
| + "/tweedledum"), false); |
| wrap.createSymlink(new Path(USER_DIR + "tweedledum"), new Path(USER_DIR |
| + "/tweedledee"), false); |
| statuses = wrap.globStatus( |
| new Path(USER_DIR + "/tweedledee/unobtainium"), |
| new AcceptAllPathFilter()); |
| Assert.assertNull(statuses); |
| } |
| } |
| |
| @Ignore |
| @Test |
| public void testGlobWithSymlinksToSymlinksOnFS() throws Exception { |
| testOnFileSystem(new TestGlobWithSymlinksToSymlinks(false)); |
| } |
| |
| @Ignore |
| @Test |
| public void testGlobWithSymlinksToSymlinksOnFC() throws Exception { |
| testOnFileContext(new TestGlobWithSymlinksToSymlinks(true)); |
| } |
| |
| /** |
| * Test globbing symlinks with a custom PathFilter |
| */ |
| private class TestGlobSymlinksWithCustomPathFilter extends |
| FSTestWrapperGlobTest { |
| TestGlobSymlinksWithCustomPathFilter(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| // Test that globbing through a symlink to a symlink to a directory |
| // fully resolves |
| wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(), |
| false); |
| wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR |
| + "/alphaLinkz"), false); |
| wrap.mkdir(new Path(USER_DIR + "/alpha/beta"), |
| FsPermission.getDirDefault(), false); |
| wrap.mkdir(new Path(USER_DIR + "/alpha/betaz"), |
| FsPermission.getDirDefault(), false); |
| // Test glob through symlink to a symlink to a directory, with a |
| // PathFilter |
| FileStatus statuses[] = wrap.globStatus( |
| new Path(USER_DIR + "/alpha/beta"), new AcceptPathsEndingInZ()); |
| Assert.assertNull(statuses); |
| statuses = wrap.globStatus(new Path(USER_DIR + "/alphaLinkz/betaz"), |
| new AcceptPathsEndingInZ()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals(USER_DIR + "/alphaLinkz/betaz", statuses[0].getPath() |
| .toUri().getPath()); |
| statuses = wrap.globStatus(new Path(USER_DIR + "/*/*"), |
| new AcceptPathsEndingInZ()); |
| Assert.assertEquals(USER_DIR + "/alpha/betaz;" + USER_DIR |
| + "/alphaLinkz/betaz", TestPath.mergeStatuses(statuses)); |
| statuses = wrap.globStatus(new Path(USER_DIR + "/*/*"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(USER_DIR + "/alpha/beta;" + USER_DIR |
| + "/alpha/betaz;" + USER_DIR + "/alphaLinkz/beta;" + USER_DIR |
| + "/alphaLinkz/betaz", TestPath.mergeStatuses(statuses)); |
| } |
| } |
| |
| @Ignore |
| @Test |
| public void testGlobSymlinksWithCustomPathFilterOnFS() throws Exception { |
| testOnFileSystem(new TestGlobSymlinksWithCustomPathFilter(false)); |
| } |
| |
| @Ignore |
| @Test |
| public void testGlobSymlinksWithCustomPathFilterOnFC() throws Exception { |
| testOnFileContext(new TestGlobSymlinksWithCustomPathFilter(true)); |
| } |
| |
| /** |
| * Test that globStatus fills in the scheme even when it is not provided. |
| */ |
| private class TestGlobFillsInScheme extends FSTestWrapperGlobTest { |
| TestGlobFillsInScheme(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| // Verify that the default scheme is hdfs, when we don't supply one. |
| wrap.mkdir(new Path(USER_DIR + "/alpha"), FsPermission.getDirDefault(), |
| false); |
| wrap.createSymlink(new Path(USER_DIR + "/alpha"), new Path(USER_DIR |
| + "/alphaLink"), false); |
| FileStatus statuses[] = wrap.globStatus( |
| new Path(USER_DIR + "/alphaLink"), new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Path path = statuses[0].getPath(); |
| Assert.assertEquals(USER_DIR + "/alpha", path.toUri().getPath()); |
| Assert.assertEquals("hdfs", path.toUri().getScheme()); |
| |
| // FileContext can list a file:/// URI. |
| // Since everyone should have the root directory, we list that. |
| statuses = fc.util().globStatus(new Path("file:///"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Path filePath = statuses[0].getPath(); |
| Assert.assertEquals("file", filePath.toUri().getScheme()); |
| Assert.assertEquals("/", filePath.toUri().getPath()); |
| |
| // The FileSystem should have scheme 'hdfs' |
| Assert.assertEquals("hdfs", fs.getScheme()); |
| } |
| } |
| |
| @Test |
| public void testGlobFillsInSchemeOnFS() throws Exception { |
| testOnFileSystem(new TestGlobFillsInScheme(false)); |
| } |
| |
| @Test |
| public void testGlobFillsInSchemeOnFC() throws Exception { |
| testOnFileContext(new TestGlobFillsInScheme(true)); |
| } |
| |
| /** |
| * Test that globStatus works with relative paths. |
| **/ |
| private class TestRelativePath extends FSTestWrapperGlobTest { |
| TestRelativePath(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| String[] files = new String[] { "a", "abc", "abc.p", "bacd" }; |
| |
| Path[] path = new Path[files.length]; |
| for(int i=0; i < files.length; i++) { |
| path[i] = wrap.makeQualified(new Path(files[i])); |
| wrap.mkdir(path[i], FsPermission.getDirDefault(), true); |
| } |
| |
| Path patternPath = new Path("a*"); |
| Path[] globResults = FileUtil.stat2Paths(wrap.globStatus(patternPath, |
| new AcceptAllPathFilter()), |
| patternPath); |
| |
| for(int i=0; i < globResults.length; i++) { |
| globResults[i] = wrap.makeQualified(globResults[i]); |
| } |
| |
| assertEquals(globResults.length, 3); |
| |
| // The default working directory for FileSystem is the user's home |
| // directory. For FileContext, the default is based on the UNIX user that |
| // started the jvm. This is arguably a bug (see HADOOP-10944 for |
| // details). We work around it here by explicitly calling |
| // getWorkingDirectory and going from there. |
| String pwd = wrap.getWorkingDirectory().toUri().getPath(); |
| assertEquals(pwd + "/a;" + pwd + "/abc;" + pwd + "/abc.p", |
| TestPath.mergeStatuses(globResults)); |
| } |
| } |
| |
| @Test |
| public void testRelativePathOnFS() throws Exception { |
| testOnFileSystem(new TestRelativePath(false)); |
| } |
| |
| @Test |
| public void testRelativePathOnFC() throws Exception { |
| testOnFileContext(new TestRelativePath(true)); |
| } |
| |
| /** |
| * Test that trying to glob through a directory we don't have permission |
| * to list fails with AccessControlException rather than succeeding or |
| * throwing any other exception. |
| **/ |
| private class TestGlobAccessDenied extends FSTestWrapperGlobTest { |
| TestGlobAccessDenied(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| privWrap.mkdir(new Path("/nopermission/val"), |
| new FsPermission((short)0777), true); |
| privWrap.mkdir(new Path("/norestrictions/val"), |
| new FsPermission((short)0777), true); |
| privWrap.setPermission(new Path("/nopermission"), |
| new FsPermission((short)0)); |
| try { |
| wrap.globStatus(new Path("/no*/*"), |
| new AcceptAllPathFilter()); |
| Assert.fail("expected to get an AccessControlException when " + |
| "globbing through a directory we don't have permissions " + |
| "to list."); |
| } catch (AccessControlException ioe) { |
| } |
| |
| Assert.assertEquals("/norestrictions/val", |
| TestPath.mergeStatuses(wrap.globStatus( |
| new Path("/norestrictions/*"), |
| new AcceptAllPathFilter()))); |
| } |
| } |
| |
| @Test |
| public void testGlobAccessDeniedOnFS() throws Exception { |
| testOnFileSystem(new TestGlobAccessDenied(false)); |
| } |
| |
| @Test |
| public void testGlobAccessDeniedOnFC() throws Exception { |
| testOnFileContext(new TestGlobAccessDenied(true)); |
| } |
| |
| /** |
| * Test that trying to list a reserved path on HDFS via the globber works. |
| **/ |
| private class TestReservedHdfsPaths extends FSTestWrapperGlobTest { |
| TestReservedHdfsPaths(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| String reservedRoot = "/.reserved/.inodes/" + INodeId.ROOT_INODE_ID; |
| Assert.assertEquals(reservedRoot, |
| TestPath.mergeStatuses(wrap. |
| globStatus(new Path(reservedRoot), new AcceptAllPathFilter()))); |
| } |
| } |
| |
| @Test |
| public void testReservedHdfsPathsOnFS() throws Exception { |
| testOnFileSystem(new TestReservedHdfsPaths(false)); |
| } |
| |
| @Test |
| public void testReservedHdfsPathsOnFC() throws Exception { |
| testOnFileContext(new TestReservedHdfsPaths(true)); |
| } |
| |
| /** |
| * Test trying to glob the root. Regression test for HDFS-5888. |
| **/ |
| private class TestGlobRoot extends FSTestWrapperGlobTest { |
| TestGlobRoot (boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| final Path rootPath = new Path("/"); |
| FileStatus oldRootStatus = wrap.getFileStatus(rootPath); |
| String newOwner = UUID.randomUUID().toString(); |
| privWrap.setOwner(new Path("/"), newOwner, null); |
| FileStatus[] status = |
| wrap.globStatus(rootPath, new AcceptAllPathFilter()); |
| Assert.assertEquals(1, status.length); |
| Assert.assertEquals(newOwner, status[0].getOwner()); |
| privWrap.setOwner(new Path("/"), oldRootStatus.getOwner(), null); |
| } |
| } |
| |
| @Test |
| public void testGlobRootOnFS() throws Exception { |
| testOnFileSystem(new TestGlobRoot(false)); |
| } |
| |
| @Test |
| public void testGlobRootOnFC() throws Exception { |
| testOnFileContext(new TestGlobRoot(true)); |
| } |
| |
| /** |
| * Test glob expressions that don't appear at the end of the path. Regression |
| * test for HADOOP-10957. |
| **/ |
| private class TestNonTerminalGlobs extends FSTestWrapperGlobTest { |
| TestNonTerminalGlobs(boolean useFc) { |
| super(useFc); |
| } |
| |
| void run() throws Exception { |
| try { |
| privWrap.mkdir(new Path("/filed_away/alpha"), |
| new FsPermission((short)0777), true); |
| privWrap.createFile(new Path("/filed"), 0); |
| FileStatus[] statuses = |
| wrap.globStatus(new Path("/filed*/alpha"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals("/filed_away/alpha", statuses[0].getPath() |
| .toUri().getPath()); |
| privWrap.mkdir(new Path("/filed_away/alphabet"), |
| new FsPermission((short)0777), true); |
| privWrap.mkdir(new Path("/filed_away/alphabet/abc"), |
| new FsPermission((short)0777), true); |
| statuses = wrap.globStatus(new Path("/filed*/alph*/*b*"), |
| new AcceptAllPathFilter()); |
| Assert.assertEquals(1, statuses.length); |
| Assert.assertEquals("/filed_away/alphabet/abc", statuses[0].getPath() |
| .toUri().getPath()); |
| } finally { |
| privWrap.delete(new Path("/filed"), true); |
| privWrap.delete(new Path("/filed_away"), true); |
| } |
| } |
| } |
| |
| @Test |
| public void testNonTerminalGlobsOnFS() throws Exception { |
| testOnFileSystem(new TestNonTerminalGlobs(false)); |
| } |
| |
| @Test |
| public void testNonTerminalGlobsOnFC() throws Exception { |
| testOnFileContext(new TestNonTerminalGlobs(true)); |
| } |
| |
| @Test |
| public void testLocalFilesystem() throws Exception { |
| Configuration conf = new Configuration(); |
| FileSystem fs = FileSystem.getLocal(conf); |
| String localTmp = System.getProperty("java.io.tmpdir"); |
| Path base = new Path(new Path(localTmp), UUID.randomUUID().toString()); |
| Assert.assertTrue(fs.mkdirs(base)); |
| Assert.assertTrue(fs.mkdirs(new Path(base, "e"))); |
| Assert.assertTrue(fs.mkdirs(new Path(base, "c"))); |
| Assert.assertTrue(fs.mkdirs(new Path(base, "a"))); |
| Assert.assertTrue(fs.mkdirs(new Path(base, "d"))); |
| Assert.assertTrue(fs.mkdirs(new Path(base, "b"))); |
| fs.deleteOnExit(base); |
| FileStatus[] status = fs.globStatus(new Path(base, "*")); |
| ArrayList list = new ArrayList(); |
| for (FileStatus f: status) { |
| list.add(f.getPath().toString()); |
| } |
| boolean sorted = Ordering.natural().isOrdered(list); |
| Assert.assertTrue(sorted); |
| } |
| } |
| |