1 /* 2 * Copyright (c) 2014, 2018, 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 /* 25 * @test 26 * @summary Basic test of jrt file system provider 27 * @run testng Basic 28 */ 29 30 import java.io.InputStream; 31 import java.io.IOError; 32 import java.io.IOException; 33 import java.io.DataInputStream; 34 import java.nio.file.DirectoryStream; 35 import java.nio.file.InvalidPathException; 36 import java.nio.file.Files; 37 import java.nio.file.FileSystem; 38 import java.nio.file.FileSystems; 39 import java.nio.file.Path; 40 import java.nio.file.PathMatcher; 41 import java.nio.file.Paths; 42 import java.net.URI; 43 import java.util.Collections; 44 import java.util.HashMap; 45 import java.util.Iterator; 46 import java.util.Map; 47 import java.util.NoSuchElementException; 48 import java.util.stream.Stream; 49 50 import org.testng.annotations.AfterClass; 51 import org.testng.annotations.BeforeClass; 52 import org.testng.annotations.DataProvider; 53 import org.testng.annotations.Test; 54 55 import static org.testng.Assert.assertEquals; 56 import static org.testng.Assert.assertNotEquals; 57 import static org.testng.Assert.assertNotNull; 58 import static org.testng.Assert.assertTrue; 59 import static org.testng.Assert.assertFalse; 60 61 /** 62 * Basic tests for jrt:/ file system provider. 63 */ 64 65 public class Basic { 66 67 private FileSystem theFileSystem; 68 private FileSystem fs; 69 private boolean isExplodedBuild = false; 70 71 @BeforeClass 72 public void setup() { 73 theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/")); 74 Path modulesPath = Paths.get(System.getProperty("java.home"), 75 "lib", "modules"); 76 isExplodedBuild = Files.notExists(modulesPath); 77 if (isExplodedBuild) { 78 System.out.printf("%s doesn't exist.", modulesPath.toString()); 79 System.out.println(); 80 System.out.println("It is most probably an exploded build." 81 + " Skip non-default FileSystem testing."); 82 return; 83 } 84 85 Map<String, String> env = new HashMap<>(); 86 // set java.home property to be underlying java.home 87 // so that jrt-fs.jar loading is exercised. 88 env.put("java.home", System.getProperty("java.home")); 89 try { 90 fs = FileSystems.newFileSystem(URI.create("jrt:/"), env); 91 } catch (IOException ioExp) { 92 throw new RuntimeException(ioExp); 93 } 94 } 95 96 @AfterClass 97 public void tearDown() { 98 try { 99 fs.close(); 100 } catch (Exception ignored) {} 101 } 102 103 private FileSystem selectFileSystem(boolean theDefault) { 104 return theDefault? theFileSystem : fs; 105 } 106 107 // Checks that the given FileSystem is a jrt file system. 108 private void checkFileSystem(FileSystem fs) { 109 assertTrue(fs.provider().getScheme().equalsIgnoreCase("jrt")); 110 assertTrue(fs.isOpen()); 111 assertTrue(fs.isReadOnly()); 112 assertEquals(fs.getSeparator(), "/"); 113 114 // one root 115 Iterator<Path> roots = fs.getRootDirectories().iterator(); 116 assertTrue(roots.next().toString().equals("/")); 117 assertFalse(roots.hasNext()); 118 } 119 120 @Test 121 public void testGetFileSystem() { 122 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 123 checkFileSystem(fs); 124 125 // getFileSystem should return the same object each time 126 assertTrue(fs == FileSystems.getFileSystem(URI.create("jrt:/"))); 127 } 128 129 @Test(expectedExceptions = UnsupportedOperationException.class) 130 public void testCloseFileSystem() throws Exception { 131 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 132 fs.close(); // should throw UOE 133 } 134 135 @Test 136 public void testNewFileSystem() throws Exception { 137 FileSystem theFileSystem = FileSystems.getFileSystem(URI.create("jrt:/")); 138 Map<String, ?> env = Collections.emptyMap(); 139 try (FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), env)) { 140 checkFileSystem(fs); 141 assertTrue(fs != theFileSystem); 142 } 143 } 144 145 @Test 146 public void testNewFileSystemWithJavaHome() throws Exception { 147 if (isExplodedBuild) { 148 System.out.println("Skip testNewFileSystemWithJavaHome" 149 + " since this is an exploded build"); 150 return; 151 } 152 153 Map<String, String> env = new HashMap<>(); 154 // set java.home property to be underlying java.home 155 // so that jrt-fs.jar loading is exercised. 156 env.put("java.home", System.getProperty("java.home")); 157 try (FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), env)) { 158 checkFileSystem(fs); 159 // jrt-fs.jar classes are loaded by another (non-boot) loader in this case 160 assertNotNull(fs.provider().getClass().getClassLoader()); 161 } 162 } 163 164 @DataProvider(name = "knownClassFiles") 165 private Object[][] knownClassFiles() { 166 return new Object[][] { 167 { "/modules/java.base/java/lang/Object.class", true }, 168 { "modules/java.base/java/lang/Object.class", true }, 169 { "/modules/java.base/java/lang/Object.class", false }, 170 { "modules/java.base/java/lang/Object.class", false }, 171 }; 172 } 173 174 @Test(dataProvider = "knownClassFiles") 175 public void testKnownClassFiles(String path, boolean theDefault) throws Exception { 176 if (isExplodedBuild && !theDefault) { 177 System.out.println("Skip testKnownClassFiles with non-default FileSystem"); 178 return; 179 } 180 181 FileSystem fs = selectFileSystem(theDefault); 182 Path classFile = fs.getPath(path); 183 184 assertTrue(Files.isRegularFile(classFile)); 185 assertTrue(Files.size(classFile) > 0L); 186 187 // check magic number 188 try (InputStream in = Files.newInputStream(classFile)) { 189 int magic = new DataInputStream(in).readInt(); 190 assertEquals(magic, 0xCAFEBABE); 191 } 192 } 193 194 @DataProvider(name = "knownDirectories") 195 private Object[][] knownDirectories() { 196 return new Object[][] { 197 { "/", true }, 198 { "." , true }, 199 { "./", true }, 200 { "/.", true }, 201 { "/./", true }, 202 { "/modules/java.base/..", true }, 203 { "/modules/java.base/../", true }, 204 { "/modules/java.base/../.", true }, 205 { "/modules/java.base", true }, 206 { "/modules/java.base/java/lang", true }, 207 { "modules/java.base/java/lang", true }, 208 { "/modules/java.base/java/lang/", true }, 209 { "modules/java.base/java/lang/", true }, 210 { "/", false }, 211 { "." , false }, 212 { "./", false }, 213 { "/.", false }, 214 { "/./", false }, 215 { "/modules/java.base/..", false }, 216 { "/modules/java.base/../", false }, 217 { "/modules/java.base/../.", false }, 218 { "/modules/java.base", false }, 219 { "/modules/java.base/java/lang", false }, 220 { "modules/java.base/java/lang", false }, 221 { "/modules/java.base/java/lang/", false }, 222 { "modules/java.base/java/lang/", false }, 223 }; 224 } 225 226 @Test(dataProvider = "knownDirectories") 227 public void testKnownDirectories(String path, boolean theDefault) throws Exception { 228 if (isExplodedBuild && !theDefault) { 229 System.out.println("Skip testKnownDirectories with non-default FileSystem"); 230 return; 231 } 232 233 FileSystem fs = selectFileSystem(theDefault); 234 Path dir = fs.getPath(path); 235 236 assertTrue(Files.isDirectory(dir)); 237 238 // directory should not be empty 239 try (Stream<Path> stream = Files.list(dir)) { 240 assertTrue(stream.count() > 0L); 241 } 242 try (Stream<Path> stream = Files.walk(dir)) { 243 assertTrue(stream.count() > 0L); 244 } 245 } 246 247 @DataProvider(name = "topLevelPkgDirs") 248 private Object[][] topLevelPkgDirs() { 249 return new Object[][] { 250 { "/java/lang" }, 251 { "java/lang" }, 252 { "/java/util" }, 253 { "java/util" }, 254 }; 255 } 256 257 @Test(dataProvider = "topLevelPkgDirs") 258 public void testNotExists(String path) throws Exception { 259 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 260 Path dir = fs.getPath(path); 261 262 // package directories should not be there at top level 263 assertTrue(Files.notExists(dir)); 264 } 265 266 /** 267 * Test the URI of every file in the jrt file system 268 */ 269 @Test 270 public void testToAndFromUri() throws Exception { 271 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 272 Path top = fs.getPath("/"); 273 try (Stream<Path> stream = Files.walk(top)) { 274 stream.forEach(path -> { 275 String pathStr = path.toAbsolutePath().toString(); 276 URI u = null; 277 try { 278 u = path.toUri(); 279 } catch (IOError e) { 280 assertFalse(pathStr.startsWith("/modules")); 281 return; 282 } 283 284 assertTrue(u.getScheme().equalsIgnoreCase("jrt")); 285 assertFalse(u.isOpaque()); 286 assertTrue(u.getAuthority() == null); 287 288 pathStr = pathStr.substring("/modules".length()); 289 if (pathStr.isEmpty()) { 290 pathStr = "/"; 291 } 292 assertEquals(u.getPath(), pathStr); 293 Path p = Paths.get(u); 294 assertEquals(p, path); 295 }); 296 } 297 } 298 299 // @bug 8216553: JrtFIleSystemProvider getPath(URI) omits /modules element from file path 300 @Test 301 public void testPathToURIConversion() throws Exception { 302 var uri = URI.create("jrt:/java.base/module-info.class"); 303 var path = Path.of(uri); 304 assertTrue(Files.exists(path)); 305 306 uri = URI.create("jrt:/java.base/../java.base/module-info.class"); 307 boolean seenIAE = false; 308 try { 309 Path.of(uri); 310 } catch (IllegalArgumentException iaExp) { 311 seenIAE = true; 312 } 313 assertTrue(seenIAE); 314 315 // check round-trip 316 var jrtfs = FileSystems.getFileSystem(URI.create("jrt:/")); 317 assertTrue(Files.exists(jrtfs.getPath(path.toString()))); 318 319 path = jrtfs.getPath("/modules/../modules/java.base/"); 320 boolean seenIOError = false; 321 try { 322 path.toUri(); 323 } catch (IOError ioError) { 324 seenIOError = true; 325 } 326 assertTrue(seenIOError); 327 } 328 329 @Test 330 public void testDirectoryNames() throws Exception { 331 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 332 Path top = fs.getPath("/"); 333 // check that directory names do not have trailing '/' char 334 try (Stream<Path> stream = Files.walk(top)) { 335 stream.skip(1).filter(Files::isDirectory).forEach(path -> { 336 assertFalse(path.toString().endsWith("/")); 337 }); 338 } 339 } 340 341 @DataProvider(name = "pathPrefixs") 342 private Object[][] pathPrefixes() { 343 return new Object[][] { 344 { "/" }, 345 { "modules/java.base/java/lang" }, 346 { "./modules/java.base/java/lang" }, 347 { "/modules/java.base/java/lang" }, 348 { "/./modules/java.base/java/lang" }, 349 { "modules/java.base/java/lang/" }, 350 { "./modules/java.base/java/lang/" }, 351 { "/./modules/java.base/java/lang/" }, 352 }; 353 } 354 355 // @Test(dataProvider = "pathPrefixes") 356 public void testParentInDirList(String dir) throws Exception { 357 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 358 Path base = fs.getPath(dir); 359 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base)) { 360 for (Path entry: stream) { 361 assertTrue( entry.getParent().equals(base), 362 base.toString() + "-> " + entry.toString() ); 363 } 364 } 365 } 366 367 @DataProvider(name = "dirStreamStringFilterData") 368 private Object[][] dirStreamStringFilterData() { 369 return new Object[][] { 370 { "/modules/java.base/java/lang", "/reflect" }, 371 { "/modules/java.base/java/lang", "/Object.class" }, 372 { "/modules/java.base/java/util", "/stream" }, 373 { "/modules/java.base/java/util", "/List.class" }, 374 }; 375 } 376 377 @Test(dataProvider = "dirStreamStringFilterData") 378 public void testDirectoryStreamStringFilter(String dir, String filter) throws Exception { 379 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 380 Path base = fs.getPath(dir); 381 try (DirectoryStream<Path> stream = 382 Files.newDirectoryStream(base, p->!p.toString().endsWith(filter))) { 383 for (Path entry: stream) { 384 assertFalse(entry.toString().contains(filter), 385 "filtered path seen: " + filter); 386 } 387 } 388 389 // make sure without filter, we do see that matching entry! 390 boolean seen = false; 391 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base)) { 392 for (Path entry: stream) { 393 if (entry.toString().endsWith(filter)) { 394 seen = true; 395 break; 396 } 397 } 398 } 399 400 assertTrue(seen, "even without filter " + filter + " is missing"); 401 } 402 403 @DataProvider(name = "dirStreamFilterData") 404 private Object[][] dirStreamFilterData() { 405 return new Object[][] { 406 { 407 "/", 408 (DirectoryStream.Filter<Path>)(Files::isDirectory), 409 "isDirectory" 410 }, 411 { 412 "/modules/java.base/java/lang", 413 (DirectoryStream.Filter<Path>)(Files::isRegularFile), 414 "isFile" 415 } 416 }; 417 } 418 419 @Test(dataProvider = "dirStreamFilterData") 420 private void testDirectoryStreamFilter(String dir, DirectoryStream.Filter filter, 421 String name) throws Exception { 422 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 423 Path base = fs.getPath(dir); 424 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base, filter)) { 425 for (Path entry: stream) { 426 assertTrue(filter.accept(entry), "filtered path seen: " + name); 427 } 428 } 429 430 // make sure without filter, we do see that matching entry! 431 boolean seen = false; 432 try (DirectoryStream<Path> stream = Files.newDirectoryStream(base)) { 433 for (Path entry: stream) { 434 if (filter.accept(entry)) { 435 seen = true; 436 break; 437 } 438 } 439 } 440 441 assertTrue(seen, "even without filter " + name + " is missing"); 442 } 443 444 @Test 445 private void testDirectoryStreamIterator() throws Exception { 446 // run the tests with null filter (no filter) 447 dirStreamIteratorTest(null); 448 // run the same tests with trivial "accept all" filter 449 dirStreamIteratorTest(p->true); 450 // two other non-trivial ones 451 dirStreamIteratorTest(Files::isDirectory); 452 dirStreamIteratorTest(Files::isRegularFile); 453 } 454 455 private void dirStreamIteratorTest(DirectoryStream.Filter<Path> filter) 456 throws Exception { 457 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 458 // This test assumes at least there are two elements in "java/lang" 459 // package with any filter passed. don't change to different path here! 460 Path dir = fs.getPath("/modules/java.base/java/lang"); 461 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 462 Iterator<Path> itr = stream.iterator(); 463 itr.hasNext(); 464 Path path1 = itr.next(); 465 // missing second hasNext call 466 Path path2 = itr.next(); 467 assertNotEquals(path1, path2); 468 } 469 470 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 471 Iterator<Path> itr = stream.iterator(); 472 // no hasNext calls at all 473 Path path1 = itr.next(); 474 Path path2 = itr.next(); 475 assertNotEquals(path1, path2); 476 } 477 478 int numEntries = 0; 479 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 480 Iterator<Path> itr = stream.iterator(); 481 while (itr.hasNext()) { 482 numEntries++; 483 itr.next(); 484 } 485 486 // reached EOF, next call should result in exception 487 try { 488 itr.next(); 489 throw new AssertionError("should have thrown exception"); 490 } catch (NoSuchElementException nsee) { 491 System.out.println("got NoSuchElementException as expected"); 492 } 493 } 494 495 // redundant hasNext calls 496 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) { 497 Iterator<Path> itr = stream.iterator(); 498 // any number of hasNext should definitely stay at first element 499 for (int i = 0; i < 2*numEntries; i++) { 500 itr.hasNext(); 501 } 502 503 for (int j = 0; j < numEntries; j++) { 504 itr.next(); 505 } 506 // exactly count number of entries! 507 assertFalse(itr.hasNext()); 508 } 509 } 510 511 @DataProvider(name = "hiddenPaths") 512 private Object[][] hiddenPaths() { 513 return new Object[][] { 514 { "/META-INF" }, 515 { "/META-INF/services" }, 516 { "/META-INF/services/java.nio.file.spi.FileSystemProvider" }, 517 { "/modules/java.base/packages.offsets" }, 518 { "/modules/java.instrument/packages.offsets" }, 519 { "/modules/jdk.zipfs/packages.offsets" }, 520 { "/modules/java.base/_the.java.base.vardeps" }, 521 { "/modules/java.base/_the.java.base_batch" }, 522 { "/java/lang" }, 523 { "/java/util" }, 524 }; 525 } 526 527 @Test(dataProvider = "hiddenPaths") 528 public void testHiddenPathsNotExposed(String path) throws Exception { 529 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 530 assertTrue(Files.notExists(fs.getPath(path)), path + " should not exist"); 531 } 532 533 @DataProvider(name = "pathGlobPatterns") 534 private Object[][] pathGlobPatterns() { 535 return new Object[][] { 536 { "/modules/*", "/modules/java.base", true }, 537 { "/modules/*", "/modules/java.base/java", false }, 538 { "/modules/j*", "/modules/java.base", true }, 539 { "/modules/J*", "/modules/java.base", false }, 540 { "**.class", "/modules/java.base/java/lang/Object.class", true }, 541 { "**.java", "/modules/java.base/java/lang/Object.class", false }, 542 { "**java/*", "/modules/java.base/java/lang", true }, 543 { "**java/lang/ref*", "/modules/java.base/java/lang/reflect", true }, 544 { "**java/lang/ref*", "/modules/java.base/java/lang/ref", true }, 545 { "**java/lang/ref?", "/modules/java.base/java/lang/ref", false }, 546 { "**java/lang/{ref,refl*}", "/modules/java.base/java/lang/ref", true }, 547 { "**java/lang/{ref,refl*}", "/modules/java.base/java/lang/reflect", true }, 548 { "**java/[a-u]?*/*.class", "/modules/java.base/java/util/Map.class", true }, 549 { "**java/util/[a-z]*.class", "/modules/java.base/java/util/TreeMap.class", false }, 550 }; 551 } 552 553 @Test(dataProvider = "pathGlobPatterns") 554 public void testGlobPathMatcher(String pattern, String path, 555 boolean expectMatch) throws Exception { 556 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 557 PathMatcher pm = fs.getPathMatcher("glob:" + pattern); 558 Path p = fs.getPath(path); 559 assertTrue(Files.exists(p), path); 560 assertTrue(!(pm.matches(p) ^ expectMatch), 561 p + (expectMatch? " should match " : " should not match ") + 562 pattern); 563 } 564 565 @DataProvider(name = "pathRegexPatterns") 566 private Object[][] pathRegexPatterns() { 567 return new Object[][] { 568 { "/modules/.*", "/modules/java.base", true }, 569 { "/modules/[^/]*", "/modules/java.base/java", false }, 570 { "/modules/j.*", "/modules/java.base", true }, 571 { "/modules/J.*", "/modules/java.base", false }, 572 { ".*\\.class", "/modules/java.base/java/lang/Object.class", true }, 573 { ".*\\.java", "/modules/java.base/java/lang/Object.class", false }, 574 { ".*java/.*", "/modules/java.base/java/lang", true }, 575 { ".*java/lang/ref.*", "/modules/java.base/java/lang/reflect", true }, 576 { ".*java/lang/ref.*", "/modules/java.base/java/lang/ref", true }, 577 { ".*/java/lang/ref.+", "/modules/java.base/java/lang/ref", false }, 578 { ".*/java/lang/(ref|refl.*)", "/modules/java.base/java/lang/ref", true }, 579 { ".*/java/lang/(ref|refl.*)", "/modules/java.base/java/lang/reflect", true }, 580 { ".*/java/[a-u]?.*/.*\\.class", "/modules/java.base/java/util/Map.class", true }, 581 { ".*/java/util/[a-z]*\\.class", "/modules/java.base/java/util/TreeMap.class", false }, 582 }; 583 } 584 585 @Test(dataProvider = "pathRegexPatterns") 586 public void testRegexPathMatcher(String pattern, String path, 587 boolean expectMatch) throws Exception { 588 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 589 PathMatcher pm = fs.getPathMatcher("regex:" + pattern); 590 Path p = fs.getPath(path); 591 assertTrue(Files.exists(p), path); 592 assertTrue(!(pm.matches(p) ^ expectMatch), 593 p + (expectMatch? " should match " : " should not match ") + 594 pattern); 595 } 596 597 @Test 598 public void testPackagesAndModules() throws Exception { 599 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 600 assertTrue(Files.isDirectory(fs.getPath("/packages"))); 601 assertTrue(Files.isDirectory(fs.getPath("/modules"))); 602 } 603 604 @DataProvider(name = "packagesSubDirs") 605 private Object[][] packagesSubDirs() { 606 return new Object[][] { 607 { "java.lang" }, 608 { "java.util" }, 609 { "java.nio" }, 610 { "jdk.nashorn.api.scripting" } 611 }; 612 } 613 614 @Test(dataProvider = "packagesSubDirs") 615 public void testPackagesSubDirs(String pkg) throws Exception { 616 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 617 assertTrue(Files.isDirectory(fs.getPath("/packages/" + pkg)), 618 pkg + " missing"); 619 } 620 621 @DataProvider(name = "packagesLinks") 622 private Object[][] packagesLinks() { 623 return new Object[][] { 624 { "/packages/java.lang/java.base" }, 625 { "/packages/java.lang/java.instrument" }, 626 { "/packages/java/java.base" }, 627 { "/packages/java/java.instrument" }, 628 { "/packages/java/java.rmi" }, 629 { "/packages/java/java.sql" }, 630 { "/packages/javax/java.base" }, 631 { "/packages/javax/java.sql" }, 632 { "/packages/javax/java.xml" }, 633 { "/packages/javax/java.management" }, 634 { "/packages/java.util/java.base" }, 635 { "/packages/jdk.nashorn.api.scripting/jdk.scripting.nashorn" }, 636 }; 637 } 638 639 @Test(dataProvider = "packagesLinks") 640 public void testPackagesLinks(String link) throws Exception { 641 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 642 Path path = fs.getPath(link); 643 assertTrue(Files.exists(path), link + " missing"); 644 assertTrue(Files.isSymbolicLink(path), path + " is not a link"); 645 path = Files.readSymbolicLink(path); 646 assertEquals(path.toString(), "/modules" + link.substring(link.lastIndexOf("/"))); 647 } 648 649 @DataProvider(name = "modulesSubDirs") 650 private Object[][] modulesSubDirs() { 651 return new Object[][] { 652 { "java.base" }, 653 { "java.sql" }, 654 { "jdk.scripting.nashorn" }, 655 }; 656 } 657 658 @Test(dataProvider = "modulesSubDirs") 659 public void testModulesSubDirs(String module) throws Exception { 660 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 661 Path path = fs.getPath("/modules/" + module); 662 assertTrue(Files.isDirectory(path), module + " missing"); 663 assertTrue(!Files.isSymbolicLink(path), path + " is a link"); 664 } 665 666 @DataProvider(name="linkChases") 667 private Object[][] linkChases() { 668 return new Object[][] { 669 { "/modules/java.base/java/lang" }, 670 { "/modules/java.base/java/util/Vector.class" }, 671 { "/modules/jdk.scripting.nashorn/jdk/nashorn" }, 672 { "/packages/java.lang/java.base/java/lang" }, 673 { "/packages/java.util/java.base/java/util/Vector.class" }, 674 }; 675 } 676 677 @Test(dataProvider = "linkChases") 678 public void testLinkChases(String link) throws Exception { 679 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 680 Path path = fs.getPath(link); 681 assertTrue(Files.exists(path), link); 682 } 683 684 @Test 685 public void testSymlinkDirList() throws Exception { 686 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 687 Path path = fs.getPath("/packages/java.lang/java.base"); 688 assertTrue(Files.isSymbolicLink(path)); 689 assertTrue(Files.isDirectory(path)); 690 691 boolean javaSeen = false, javaxSeen = false; 692 try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) { 693 for (Path p : stream) { 694 String str = p.toString(); 695 if (str.endsWith("/java")) { 696 javaSeen = true; 697 } else if (str.endsWith("javax")) { 698 javaxSeen = true; 699 } 700 } 701 } 702 assertTrue(javaSeen); 703 assertTrue(javaxSeen); 704 } 705 706 @Test 707 public void invalidPathTest() { 708 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 709 InvalidPathException ipe = null; 710 try { 711 boolean res = Files.exists(fs.getPath("/packages/\ud834\udd7b")); 712 assertFalse(res); 713 return; 714 } catch (InvalidPathException e) { 715 ipe = e; 716 } 717 assertTrue(ipe != null); 718 } 719 720 @DataProvider(name="packagesLinkedDirs") 721 private Object[][] packagesLinkedDirs() { 722 return new Object[][] { 723 { "/packages/java.lang/java.base/java/lang/ref" }, 724 { "/./packages/java.lang/java.base/java/lang/ref" }, 725 { "packages/java.lang/java.base/java/lang/ref" }, 726 { "/packages/../packages/java.lang/java.base/java/lang/ref" }, 727 { "/packages/java.lang/java.base/java/util/zip" }, 728 { "/./packages/java.lang/java.base/java/util/zip" }, 729 { "packages/java.lang/java.base/java/util/zip" }, 730 { "/packages/../packages/java.lang/java.base/java/util/zip" }, 731 }; 732 } 733 734 // @bug 8141521: jrt file system's DirectoryStream reports child paths 735 // with wrong paths for directories under /packages 736 @Test(dataProvider = "packagesLinkedDirs") 737 public void dirStreamPackagesDirTest(String dirName) throws IOException { 738 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 739 Path path = fs.getPath(dirName); 740 741 int childCount = 0, dirPrefixOkayCount = 0; 742 try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(path)) { 743 for (Path child : dirStream) { 744 childCount++; 745 if (child.toString().startsWith(dirName)) { 746 dirPrefixOkayCount++; 747 } 748 } 749 } 750 751 assertTrue(childCount != 0); 752 assertEquals(dirPrefixOkayCount, childCount); 753 } 754 755 @Test 756 public void objectClassSizeTest() throws Exception { 757 String path = "/modules/java.base/java/lang/Object.class"; 758 FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 759 Path classFile = fs.getPath(path); 760 761 assertTrue(Files.size(classFile) > 0L); 762 } 763 } 764