1 /* 2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 4313887 6838333 26 * @summary Unit test for java.nio.file.attribute.PosixFileAttributeView 27 * @library ../.. 28 */ 29 // Android-changed: Adapted from 30 // jdk/test/java/nio/file/attribute/PosixFileAttributeView/Basic.java 31 // Android-changed: Added package & Test import 32 package test.java.nio.file.attribute; 33 import org.testng.annotations.Test; 34 import test.java.nio.file.TestUtil; 35 36 import java.nio.file.*; 37 import static java.nio.file.LinkOption.*; 38 import java.nio.file.attribute.*; 39 import java.io.IOException; 40 import java.util.*; 41 42 /** 43 * Unit test for PosixFileAttributeView, passing silently if this attribute 44 * view is not available. 45 */ 46 47 // Android-changed: Renamed from "Basic" 48 public class PosixFileAttributeViewTest { 49 50 /** 51 * Use view to update permission to the given mode and check that the 52 * permissions have been updated. 53 */ 54 static void testPermissions(Path file, String mode) throws IOException { 55 System.out.format("change mode: %s\n", mode); 56 Set<PosixFilePermission> perms = PosixFilePermissions.fromString(mode); 57 58 // change permissions and re-read them. 59 Files.setPosixFilePermissions(file, perms); 60 Set<PosixFilePermission> current = Files.getPosixFilePermissions(file); 61 if (!current.equals(perms)) { 62 throw new RuntimeException("Actual permissions: " + 63 PosixFilePermissions.toString(current) + ", expected: " + 64 PosixFilePermissions.toString(perms)); 65 } 66 67 // repeat test using setAttribute/getAttribute 68 Files.setAttribute(file, "posix:permissions", perms); 69 current = (Set<PosixFilePermission>)Files.getAttribute(file, "posix:permissions"); 70 if (!current.equals(perms)) { 71 throw new RuntimeException("Actual permissions: " + 72 PosixFilePermissions.toString(current) + ", expected: " + 73 PosixFilePermissions.toString(perms)); 74 } 75 } 76 77 /** 78 * Check that the actual permissions of a file match or make it more 79 * secure than requested 80 */ 81 static void checkSecure(Set<PosixFilePermission> requested, 82 Set<PosixFilePermission> actual) 83 { 84 for (PosixFilePermission perm: actual) { 85 if (!requested.contains(perm)) { 86 throw new RuntimeException("Actual permissions: " + 87 PosixFilePermissions.toString(actual) + ", requested: " + 88 PosixFilePermissions.toString(requested) + 89 " - file is less secure than requested"); 90 } 91 } 92 } 93 94 /** 95 * Create file with given mode and check that the file is created with a 96 * mode that is not less secure 97 */ 98 static void createWithPermissions(Path file, 99 String mode) 100 throws IOException 101 { 102 Set<PosixFilePermission> requested = PosixFilePermissions.fromString(mode); 103 FileAttribute<Set<PosixFilePermission>> attr = 104 PosixFilePermissions.asFileAttribute(requested); 105 System.out.format("create file with mode: %s\n", mode); 106 Files.createFile(file, attr); 107 try { 108 checkSecure(requested, 109 Files.getFileAttributeView(file, PosixFileAttributeView.class) 110 .readAttributes() 111 .permissions()); 112 } finally { 113 Files.delete(file); 114 } 115 116 System.out.format("create directory with mode: %s\n", mode); 117 Files.createDirectory(file, attr); 118 try { 119 checkSecure(requested, 120 Files.getFileAttributeView(file, PosixFileAttributeView.class) 121 .readAttributes() 122 .permissions()); 123 } finally { 124 Files.delete(file); 125 } 126 } 127 128 /** 129 * Test the setPermissions/permissions methods. 130 */ 131 static void permissionTests(Path dir) 132 throws IOException 133 { 134 System.out.println("-- Permission Tests --"); 135 136 // create file and test updating and reading its permissions 137 Path file = dir.resolve("foo"); 138 System.out.format("create %s\n", file); 139 Files.createFile(file); 140 try { 141 // get initial permissions so that we can restore them later 142 PosixFileAttributeView view = 143 Files.getFileAttributeView(file, PosixFileAttributeView.class); 144 Set<PosixFilePermission> save = view.readAttributes() 145 .permissions(); 146 147 // test various modes 148 try { 149 testPermissions(file, "---------"); 150 testPermissions(file, "r--------"); 151 testPermissions(file, "-w-------"); 152 testPermissions(file, "--x------"); 153 testPermissions(file, "rwx------"); 154 testPermissions(file, "---r-----"); 155 testPermissions(file, "----w----"); 156 testPermissions(file, "-----x---"); 157 testPermissions(file, "---rwx---"); 158 testPermissions(file, "------r--"); 159 testPermissions(file, "-------w-"); 160 testPermissions(file, "--------x"); 161 testPermissions(file, "------rwx"); 162 testPermissions(file, "r--r-----"); 163 testPermissions(file, "r--r--r--"); 164 testPermissions(file, "rw-rw----"); 165 testPermissions(file, "rwxrwx---"); 166 testPermissions(file, "rw-rw-r--"); 167 testPermissions(file, "r-xr-x---"); 168 testPermissions(file, "r-xr-xr-x"); 169 testPermissions(file, "rwxrwxrwx"); 170 } finally { 171 view.setPermissions(save); 172 } 173 } finally { 174 Files.delete(file); 175 } 176 177 // create link (to file that doesn't exist) and test reading of 178 // permissions 179 if (TestUtil.supportsLinks(dir)) { 180 Path link = dir.resolve("link"); 181 System.out.format("create link %s\n", link); 182 Files.createSymbolicLink(link, file); 183 try { 184 PosixFileAttributes attrs = 185 Files.getFileAttributeView(link, 186 PosixFileAttributeView.class, 187 NOFOLLOW_LINKS) 188 .readAttributes(); 189 if (!attrs.isSymbolicLink()) { 190 throw new RuntimeException("not a link"); 191 } 192 } finally { 193 Files.delete(link); 194 } 195 } 196 197 System.out.println("OKAY"); 198 } 199 200 /** 201 * Test creating a file and directory with initial permissios 202 */ 203 static void createTests(Path dir) 204 throws IOException 205 { 206 System.out.println("-- Create Tests --"); 207 208 Path file = dir.resolve("foo"); 209 210 createWithPermissions(file, "---------"); 211 createWithPermissions(file, "r--------"); 212 createWithPermissions(file, "-w-------"); 213 createWithPermissions(file, "--x------"); 214 createWithPermissions(file, "rwx------"); 215 createWithPermissions(file, "---r-----"); 216 createWithPermissions(file, "----w----"); 217 createWithPermissions(file, "-----x---"); 218 createWithPermissions(file, "---rwx---"); 219 createWithPermissions(file, "------r--"); 220 createWithPermissions(file, "-------w-"); 221 createWithPermissions(file, "--------x"); 222 createWithPermissions(file, "------rwx"); 223 createWithPermissions(file, "r--r-----"); 224 createWithPermissions(file, "r--r--r--"); 225 createWithPermissions(file, "rw-rw----"); 226 createWithPermissions(file, "rwxrwx---"); 227 createWithPermissions(file, "rw-rw-r--"); 228 createWithPermissions(file, "r-xr-x---"); 229 createWithPermissions(file, "r-xr-xr-x"); 230 createWithPermissions(file, "rwxrwxrwx"); 231 232 System.out.println("OKAY"); 233 } 234 235 /** 236 * Test setOwner/setGroup methods - this test simply exercises the 237 * methods to avoid configuration. 238 */ 239 static void ownerTests(Path dir) 240 throws IOException 241 { 242 System.out.println("-- Owner Tests --"); 243 244 Path file = dir.resolve("gus"); 245 System.out.format("create %s\n", file); 246 247 Files.createFile(file); 248 try { 249 250 // read attributes of directory to get owner/group 251 PosixFileAttributeView view = 252 Files.getFileAttributeView(file, PosixFileAttributeView.class); 253 PosixFileAttributes attrs = view.readAttributes(); 254 255 // set to existing owner/group 256 view.setOwner(attrs.owner()); 257 view.setGroup(attrs.group()); 258 259 // repeat test using set/getAttribute 260 UserPrincipal owner = (UserPrincipal)Files.getAttribute(file, "posix:owner"); 261 Files.setAttribute(file, "posix:owner", owner); 262 UserPrincipal group = (UserPrincipal)Files.getAttribute(file, "posix:group"); 263 Files.setAttribute(file, "posix:group", group); 264 265 } finally { 266 Files.delete(file); 267 } 268 269 System.out.println("OKAY"); 270 } 271 272 /** 273 * Test the lookupPrincipalByName/lookupPrincipalByGroupName methods 274 */ 275 static void lookupPrincipalTests(Path dir) 276 throws IOException 277 { 278 System.out.println("-- Lookup UserPrincipal Tests --"); 279 280 UserPrincipalLookupService lookupService = dir.getFileSystem() 281 .getUserPrincipalLookupService(); 282 283 // read attributes of directory to get owner/group 284 PosixFileAttributes attrs = Files.readAttributes(dir, PosixFileAttributes.class); 285 286 // lookup owner and check it matches file's owner 287 System.out.format("lookup: %s\n", attrs.owner().getName()); 288 try { 289 UserPrincipal owner = lookupService.lookupPrincipalByName(attrs.owner().getName()); 290 if (owner instanceof GroupPrincipal) 291 throw new RuntimeException("owner is a group?"); 292 if (!owner.equals(attrs.owner())) 293 throw new RuntimeException("owner different from file owner"); 294 } catch (UserPrincipalNotFoundException x) { 295 System.out.println("user not found - test skipped"); 296 } 297 298 // lookup group and check it matches file's group-owner 299 System.out.format("lookup group: %s\n", attrs.group().getName()); 300 try { 301 GroupPrincipal group = lookupService.lookupPrincipalByGroupName(attrs.group().getName()); 302 if (!group.equals(attrs.group())) 303 throw new RuntimeException("group different from file group-owner"); 304 } catch (UserPrincipalNotFoundException x) { 305 System.out.println("group not found - test skipped"); 306 } 307 308 // test that UserPrincipalNotFoundException is thrown 309 String invalidPrincipal = "scumbag99"; 310 try { 311 System.out.format("lookup: %s\n", invalidPrincipal); 312 lookupService.lookupPrincipalByName(invalidPrincipal); 313 throw new RuntimeException("'" + invalidPrincipal + "' is a valid user?"); 314 } catch (UserPrincipalNotFoundException x) { 315 } 316 try { 317 System.out.format("lookup group: %s\n", invalidPrincipal); 318 lookupService.lookupPrincipalByGroupName("idonotexist"); 319 throw new RuntimeException("'" + invalidPrincipal + "' is a valid group?"); 320 } catch (UserPrincipalNotFoundException x) { 321 } 322 System.out.println("OKAY"); 323 } 324 325 /** 326 * Test various exceptions are thrown as expected 327 */ 328 @SuppressWarnings("unchecked") 329 static void exceptionsTests(Path dir) 330 throws IOException 331 { 332 System.out.println("-- Exceptions --"); 333 334 PosixFileAttributeView view = 335 Files.getFileAttributeView(dir,PosixFileAttributeView.class); 336 337 // NullPointerException 338 try { 339 view.setOwner(null); 340 throw new RuntimeException("NullPointerException not thrown"); 341 } catch (NullPointerException x) { 342 } 343 try { 344 view.setGroup(null); 345 throw new RuntimeException("NullPointerException not thrown"); 346 } catch (NullPointerException x) { 347 } 348 349 UserPrincipalLookupService lookupService = dir.getFileSystem() 350 .getUserPrincipalLookupService(); 351 try { 352 lookupService.lookupPrincipalByName(null); 353 throw new RuntimeException("NullPointerException not thrown"); 354 } catch (NullPointerException x) { 355 } 356 try { 357 lookupService.lookupPrincipalByGroupName(null); 358 throw new RuntimeException("NullPointerException not thrown"); 359 } catch (NullPointerException x) { 360 } 361 try { 362 view.setPermissions(null); 363 throw new RuntimeException("NullPointerException not thrown"); 364 } catch (NullPointerException x) { 365 } 366 try { 367 Set<PosixFilePermission> perms = new HashSet<>(); 368 perms.add(null); 369 view.setPermissions(perms); 370 throw new RuntimeException("NullPointerException not thrown"); 371 } catch (NullPointerException x) { 372 } 373 374 // ClassCastException 375 try { 376 Set perms = new HashSet(); // raw type 377 perms.add(new Object()); 378 view.setPermissions(perms); 379 throw new RuntimeException("ClassCastException not thrown"); 380 } catch (ClassCastException x) { 381 } 382 383 System.out.println("OKAY"); 384 } 385 386 // Android-changed: Removed args & added @Test 387 @Test 388 public static void main() throws IOException { 389 Path dir = TestUtil.createTemporaryDirectory(); 390 try { 391 // Android-changed: PosixFileAttributeViews are unconditionally supported in 392 // all writeable partitions. 393 // 394 // if (!Files.getFileStore(dir).supportsFileAttributeView("posix")) { 395 // System.out.println("PosixFileAttributeView not supported"); 396 // return; 397 // } 398 399 permissionTests(dir); 400 createTests(dir); 401 ownerTests(dir); 402 lookupPrincipalTests(dir); 403 exceptionsTests(dir); 404 405 } finally { 406 TestUtil.removeAll(dir); 407 } 408 } 409 } 410