1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.fs; 19 20 import java.io.IOException; 21 import java.security.PrivilegedExceptionAction; 22 import java.util.ArrayList; 23 import java.util.List; 24 import java.util.StringTokenizer; 25 26 import org.junit.Assert; 27 28 import org.apache.hadoop.fs.permission.FsPermission; 29 import org.apache.hadoop.security.UserGroupInformation; 30 import org.apache.hadoop.util.Shell; 31 import org.apache.hadoop.util.StringUtils; 32 import org.junit.After; 33 import org.junit.Before; 34 import org.junit.Test; 35 36 import static org.apache.hadoop.fs.FileContextTestHelper.*; 37 import static org.junit.Assert.assertEquals; 38 import static org.junit.Assert.fail; 39 40 /** 41 * <p> 42 * A collection of permission tests for the {@link FileContext}. 43 * This test should be used for testing an instance of FileContext 44 * that has been initialized to a specific default FileSystem such a 45 * LocalFileSystem, HDFS,S3, etc. 46 * </p> 47 * <p> 48 * To test a given {@link FileSystem} implementation create a subclass of this 49 * test and override {@link #setUp()} to initialize the <code>fc</code> 50 * {@link FileContext} instance variable. 51 * 52 * Since this a junit 4 you can also do a single setup before 53 * the start of any tests. 54 * E.g. 55 * @BeforeClass public static void clusterSetupAtBegining() 56 * @AfterClass public static void ClusterShutdownAtEnd() 57 * </p> 58 */ 59 public abstract class FileContextPermissionBase { 60 61 { 62 try { 63 ((org.apache.commons.logging.impl.Log4JLogger)FileSystem.LOG).getLogger() 64 .setLevel(org.apache.log4j.Level.DEBUG); 65 } 66 catch(Exception e) { 67 System.out.println("Cannot change log level\n" 68 + StringUtils.stringifyException(e)); 69 } 70 } 71 72 protected FileContextTestHelper fileContextTestHelper; 73 protected FileContext fc; 74 getFileContextHelper()75 protected FileContextTestHelper getFileContextHelper() { 76 return new FileContextTestHelper(); 77 } 78 getFileContext()79 protected abstract FileContext getFileContext() throws Exception; 80 81 @Before setUp()82 public void setUp() throws Exception { 83 fileContextTestHelper = getFileContextHelper(); 84 fc = getFileContext(); 85 fc.mkdir(fileContextTestHelper.getTestRootPath(fc), FileContext.DEFAULT_PERM, true); 86 } 87 88 @After tearDown()89 public void tearDown() throws Exception { 90 fc.delete(fileContextTestHelper.getTestRootPath(fc), true); 91 } 92 cleanupFile(FileContext fc, Path name)93 private void cleanupFile(FileContext fc, Path name) throws IOException { 94 Assert.assertTrue(exists(fc, name)); 95 fc.delete(name, true); 96 Assert.assertTrue(!exists(fc, name)); 97 } 98 99 @Test testCreatePermission()100 public void testCreatePermission() throws IOException { 101 if (Path.WINDOWS) { 102 System.out.println("Cannot run test for Windows"); 103 return; 104 } 105 String filename = "foo"; 106 Path f = fileContextTestHelper.getTestRootPath(fc, filename); 107 fileContextTestHelper.createFile(fc, filename); 108 doFilePermissionCheck(FileContext.FILE_DEFAULT_PERM.applyUMask(fc.getUMask()), 109 fc.getFileStatus(f).getPermission()); 110 } 111 112 113 @Test testSetPermission()114 public void testSetPermission() throws IOException { 115 if (Path.WINDOWS) { 116 System.out.println("Cannot run test for Windows"); 117 return; 118 } 119 120 String filename = "foo"; 121 Path f = fileContextTestHelper.getTestRootPath(fc, filename); 122 createFile(fc, f); 123 124 try { 125 // create files and manipulate them. 126 FsPermission all = new FsPermission((short)0777); 127 FsPermission none = new FsPermission((short)0); 128 129 fc.setPermission(f, none); 130 doFilePermissionCheck(none, fc.getFileStatus(f).getPermission()); 131 132 fc.setPermission(f, all); 133 doFilePermissionCheck(all, fc.getFileStatus(f).getPermission()); 134 } 135 finally {cleanupFile(fc, f);} 136 } 137 138 @Test testSetOwner()139 public void testSetOwner() throws IOException { 140 if (Path.WINDOWS) { 141 System.out.println("Cannot run test for Windows"); 142 return; 143 } 144 145 String filename = "bar"; 146 Path f = fileContextTestHelper.getTestRootPath(fc, filename); 147 createFile(fc, f); 148 List<String> groups = null; 149 try { 150 groups = getGroups(); 151 System.out.println(filename + ": " + fc.getFileStatus(f).getPermission()); 152 } 153 catch(IOException e) { 154 System.out.println(StringUtils.stringifyException(e)); 155 System.out.println("Cannot run test"); 156 return; 157 } 158 if (groups == null || groups.size() < 1) { 159 System.out.println("Cannot run test: need at least one group. groups=" 160 + groups); 161 return; 162 } 163 164 // create files and manipulate them. 165 try { 166 String g0 = groups.get(0); 167 fc.setOwner(f, null, g0); 168 Assert.assertEquals(g0, fc.getFileStatus(f).getGroup()); 169 170 if (groups.size() > 1) { 171 String g1 = groups.get(1); 172 fc.setOwner(f, null, g1); 173 Assert.assertEquals(g1, fc.getFileStatus(f).getGroup()); 174 } else { 175 System.out.println("Not testing changing the group since user " + 176 "belongs to only one group."); 177 } 178 179 try { 180 fc.setOwner(f, null, null); 181 fail("Exception expected."); 182 } catch (IllegalArgumentException iae) { 183 // okay 184 } 185 } 186 finally {cleanupFile(fc, f);} 187 } 188 189 @Test testUgi()190 public void testUgi() throws IOException, InterruptedException { 191 192 UserGroupInformation otherUser = UserGroupInformation 193 .createRemoteUser("otherUser"); 194 FileContext newFc = otherUser.doAs(new PrivilegedExceptionAction<FileContext>() { 195 196 @Override 197 public FileContext run() throws Exception { 198 FileContext newFc = FileContext.getFileContext(); 199 return newFc; 200 } 201 202 }); 203 assertEquals("otherUser",newFc.getUgi().getUserName()); 204 } 205 getGroups()206 static List<String> getGroups() throws IOException { 207 List<String> a = new ArrayList<String>(); 208 String s = Shell.execCommand(Shell.getGroupsCommand()); 209 for(StringTokenizer t = new StringTokenizer(s); t.hasMoreTokens(); ) { 210 a.add(t.nextToken()); 211 } 212 return a; 213 } 214 215 doFilePermissionCheck(FsPermission expectedPerm, FsPermission actualPerm)216 void doFilePermissionCheck(FsPermission expectedPerm, FsPermission actualPerm) { 217 Assert.assertEquals(expectedPerm.applyUMask(getFileMask()), actualPerm); 218 } 219 220 221 /* 222 * Override the method below if the file system being tested masks our 223 * certain bits for file masks. 224 */ 225 static final FsPermission FILE_MASK_ZERO = new FsPermission((short) 0); getFileMask()226 FsPermission getFileMask() { 227 return FILE_MASK_ZERO; 228 } 229 } 230