1 /* 2 * Copyright (c) 2013, 2015, 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 8006884 8019526 8132539 26 * @library .. 27 * @build PassThroughFileSystem FaultyFileSystem 28 * @run testng StreamTest 29 * @summary Unit test for java.nio.file.Files methods that return a Stream 30 */ 31 32 import java.io.IOException; 33 import java.io.UncheckedIOException; 34 import java.nio.charset.Charset; 35 import java.nio.charset.MalformedInputException; 36 import java.nio.file.DirectoryIteratorException; 37 import java.nio.file.DirectoryStream; 38 import java.nio.file.FileSystemLoopException; 39 import java.nio.file.FileVisitOption; 40 import java.nio.file.Files; 41 import java.nio.file.NoSuchFileException; 42 import java.nio.file.Path; 43 import java.nio.file.Paths; 44 import java.nio.file.attribute.BasicFileAttributes; 45 import java.util.Arrays; 46 import java.util.Collections; 47 import java.util.Iterator; 48 import java.util.List; 49 import java.util.Objects; 50 import java.util.Set; 51 import java.util.TreeSet; 52 import java.util.concurrent.Callable; 53 import java.util.function.BiPredicate; 54 import java.util.stream.Stream; 55 import java.util.stream.Collectors; 56 import org.testng.annotations.AfterClass; 57 import org.testng.annotations.BeforeClass; 58 import org.testng.annotations.Test; 59 import static org.testng.Assert.*; 60 61 @Test(groups = "unit") 62 public class StreamTest { 63 /** 64 * Default test folder 65 * testFolder - empty 66 * - file 67 * - dir - d1 68 * - f1 69 * - lnDir2 (../dir2) 70 * - dir2 71 * - linkDir (./dir) 72 * - linkFile(./file) 73 */ 74 static Path testFolder; 75 static boolean supportsLinks; 76 static Path[] level1; 77 static Path[] all; 78 static Path[] all_folowLinks; 79 80 @BeforeClass setupTestFolder()81 void setupTestFolder() throws IOException { 82 testFolder = TestUtil.createTemporaryDirectory(); 83 supportsLinks = TestUtil.supportsLinks(testFolder); 84 TreeSet<Path> set = new TreeSet<>(); 85 86 // Level 1 87 Path empty = testFolder.resolve("empty"); 88 Path file = testFolder.resolve("file"); 89 Path dir = testFolder.resolve("dir"); 90 Path dir2 = testFolder.resolve("dir2"); 91 Files.createDirectory(empty); 92 Files.createFile(file); 93 Files.createDirectory(dir); 94 Files.createDirectory(dir2); 95 set.add(empty); 96 set.add(file); 97 set.add(dir); 98 set.add(dir2); 99 if (supportsLinks) { 100 Path tmp = testFolder.resolve("linkDir"); 101 Files.createSymbolicLink(tmp, dir); 102 set.add(tmp); 103 tmp = testFolder.resolve("linkFile"); 104 Files.createSymbolicLink(tmp, file); 105 set.add(tmp); 106 } 107 level1 = set.toArray(new Path[0]); 108 109 // Level 2 110 Path tmp = dir.resolve("d1"); 111 Files.createDirectory(tmp); 112 set.add(tmp); 113 tmp = dir.resolve("f1"); 114 Files.createFile(tmp); 115 set.add(tmp); 116 if (supportsLinks) { 117 tmp = dir.resolve("lnDir2"); 118 Files.createSymbolicLink(tmp, dir2); 119 set.add(tmp); 120 } 121 // walk include starting folder 122 set.add(testFolder); 123 all = set.toArray(new Path[0]); 124 125 // Follow links 126 if (supportsLinks) { 127 tmp = testFolder.resolve("linkDir"); 128 set.add(tmp.resolve("d1")); 129 set.add(tmp.resolve("f1")); 130 tmp = tmp.resolve("lnDir2"); 131 set.add(tmp); 132 } 133 all_folowLinks = set.toArray(new Path[0]); 134 } 135 136 @AfterClass cleanupTestFolder()137 void cleanupTestFolder() throws IOException { 138 TestUtil.removeAll(testFolder); 139 } 140 testBasic()141 public void testBasic() { 142 try (Stream<Path> s = Files.list(testFolder)) { 143 Object[] actual = s.sorted().toArray(); 144 assertEquals(actual, level1); 145 } catch (IOException ioe) { 146 fail("Unexpected IOException"); 147 } 148 149 try (Stream<Path> s = Files.list(testFolder.resolve("empty"))) { 150 int count = s.mapToInt(p -> 1).reduce(0, Integer::sum); 151 assertEquals(count, 0, "Expect empty stream."); 152 } catch (IOException ioe) { 153 fail("Unexpected IOException"); 154 } 155 } 156 testWalk()157 public void testWalk() { 158 try (Stream<Path> s = Files.walk(testFolder)) { 159 Object[] actual = s.sorted().toArray(); 160 assertEquals(actual, all); 161 } catch (IOException ioe) { 162 fail("Unexpected IOException"); 163 } 164 } 165 testWalkOneLevel()166 public void testWalkOneLevel() { 167 try (Stream<Path> s = Files.walk(testFolder, 1)) { 168 Object[] actual = s.filter(path -> ! path.equals(testFolder)) 169 .sorted() 170 .toArray(); 171 assertEquals(actual, level1); 172 } catch (IOException ioe) { 173 fail("Unexpected IOException"); 174 } 175 } 176 testWalkFollowLink()177 public void testWalkFollowLink() { 178 // If link is not supported, the directory structure won't have link. 179 // We still want to test the behavior with FOLLOW_LINKS option. 180 try (Stream<Path> s = Files.walk(testFolder, FileVisitOption.FOLLOW_LINKS)) { 181 Object[] actual = s.sorted().toArray(); 182 assertEquals(actual, all_folowLinks); 183 } catch (IOException ioe) { 184 fail("Unexpected IOException"); 185 } 186 } 187 validateFileSystemLoopException(Path start, Path... causes)188 private void validateFileSystemLoopException(Path start, Path... causes) { 189 try (Stream<Path> s = Files.walk(start, FileVisitOption.FOLLOW_LINKS)) { 190 try { 191 int count = s.mapToInt(p -> 1).reduce(0, Integer::sum); 192 fail("Should got FileSystemLoopException, but got " + count + "elements."); 193 } catch (UncheckedIOException uioe) { 194 IOException ioe = uioe.getCause(); 195 if (ioe instanceof FileSystemLoopException) { 196 FileSystemLoopException fsle = (FileSystemLoopException) ioe; 197 boolean match = false; 198 for (Path cause: causes) { 199 if (fsle.getFile().equals(cause.toString())) { 200 match = true; 201 break; 202 } 203 } 204 assertTrue(match); 205 } else { 206 fail("Unexpected UncheckedIOException cause " + ioe.toString()); 207 } 208 } 209 } catch(IOException ex) { 210 fail("Unexpected IOException " + ex); 211 } 212 } 213 testWalkFollowLinkLoop()214 public void testWalkFollowLinkLoop() { 215 if (!supportsLinks) { 216 return; 217 } 218 219 // Loops. 220 try { 221 Path dir = testFolder.resolve("dir"); 222 Path linkdir = testFolder.resolve("linkDir"); 223 Path d1 = dir.resolve("d1"); 224 Path cause = d1.resolve("lnSelf"); 225 Files.createSymbolicLink(cause, d1); 226 227 // loop in descendant. 228 validateFileSystemLoopException(dir, cause); 229 // loop in self 230 validateFileSystemLoopException(d1, cause); 231 // start from other place via link 232 validateFileSystemLoopException(linkdir, 233 linkdir.resolve(Paths.get("d1", "lnSelf"))); 234 Files.delete(cause); 235 236 // loop to parent. 237 cause = d1.resolve("lnParent"); 238 Files.createSymbolicLink(cause, dir); 239 240 // loop should be detected at test/dir/d1/lnParent/d1 241 validateFileSystemLoopException(d1, cause.resolve("d1")); 242 // loop should be detected at link 243 validateFileSystemLoopException(dir, cause); 244 // loop should be detected at test/linkdir/d1/lnParent 245 // which is test/dir we have visited via test/linkdir 246 validateFileSystemLoopException(linkdir, 247 linkdir.resolve(Paths.get("d1", "lnParent"))); 248 Files.delete(cause); 249 250 // cross loop 251 Path dir2 = testFolder.resolve("dir2"); 252 cause = dir2.resolve("lnDir"); 253 Files.createSymbolicLink(cause, dir); 254 validateFileSystemLoopException(dir, 255 dir.resolve(Paths.get("lnDir2", "lnDir"))); 256 validateFileSystemLoopException(dir2, 257 dir2.resolve(Paths.get("lnDir", "lnDir2"))); 258 validateFileSystemLoopException(linkdir, 259 linkdir.resolve(Paths.get("lnDir2", "lnDir"))); 260 } catch(IOException ioe) { 261 fail("Unexpected IOException " + ioe); 262 } 263 } 264 265 private static class PathBiPredicate implements BiPredicate<Path, BasicFileAttributes> { 266 private final BiPredicate<Path, BasicFileAttributes> pred; 267 private final Set<Path> visited = new TreeSet<Path>(); 268 PathBiPredicate(BiPredicate<Path, BasicFileAttributes> pred)269 PathBiPredicate(BiPredicate<Path, BasicFileAttributes> pred) { 270 this.pred = Objects.requireNonNull(pred); 271 } 272 test(Path path, BasicFileAttributes attrs)273 public boolean test(Path path, BasicFileAttributes attrs) { 274 visited.add(path); 275 return pred.test(path, attrs); 276 } 277 visited()278 public Path[] visited() { 279 return visited.toArray(new Path[0]); 280 } 281 } 282 testFind()283 public void testFind() throws IOException { 284 PathBiPredicate pred = new PathBiPredicate((path, attrs) -> true); 285 286 try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { 287 Set<Path> result = s.collect(Collectors.toCollection(TreeSet::new)); 288 assertEquals(pred.visited(), all); 289 assertEquals(result.toArray(new Path[0]), pred.visited()); 290 } 291 292 pred = new PathBiPredicate((path, attrs) -> attrs.isSymbolicLink()); 293 try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { 294 s.forEach(path -> assertTrue(Files.isSymbolicLink(path))); 295 assertEquals(pred.visited(), all); 296 } 297 298 pred = new PathBiPredicate((path, attrs) -> 299 path.getFileName().toString().startsWith("e")); 300 try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { 301 s.forEach(path -> assertEquals(path.getFileName().toString(), "empty")); 302 assertEquals(pred.visited(), all); 303 } 304 305 pred = new PathBiPredicate((path, attrs) -> 306 path.getFileName().toString().startsWith("l") && attrs.isRegularFile()); 307 try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) { 308 s.forEach(path -> fail("Expect empty stream")); 309 assertEquals(pred.visited(), all); 310 } 311 } 312 313 // Test borrowed from BytesAndLines testLines()314 public void testLines() throws IOException { 315 final Charset US_ASCII = Charset.forName("US-ASCII"); 316 Path tmpfile = Files.createTempFile("blah", "txt"); 317 318 try { 319 // zero lines 320 assertTrue(Files.size(tmpfile) == 0, "File should be empty"); 321 try (Stream<String> s = Files.lines(tmpfile)) { 322 checkLines(s, Collections.emptyList()); 323 } 324 try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) { 325 checkLines(s, Collections.emptyList()); 326 } 327 328 // one line 329 List<String> oneLine = Arrays.asList("hi"); 330 Files.write(tmpfile, oneLine, US_ASCII); 331 try (Stream<String> s = Files.lines(tmpfile)) { 332 checkLines(s, oneLine); 333 } 334 try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) { 335 checkLines(s, oneLine); 336 } 337 338 // two lines using platform's line separator 339 List<String> twoLines = Arrays.asList("hi", "there"); 340 Files.write(tmpfile, twoLines, US_ASCII); 341 try (Stream<String> s = Files.lines(tmpfile)) { 342 checkLines(s, twoLines); 343 } 344 try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) { 345 checkLines(s, twoLines); 346 } 347 348 // MalformedInputException 349 byte[] bad = { (byte)0xff, (byte)0xff }; 350 Files.write(tmpfile, bad); 351 try (Stream<String> s = Files.lines(tmpfile)) { 352 checkMalformedInputException(s); 353 } 354 try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) { 355 checkMalformedInputException(s); 356 } 357 358 // NullPointerException 359 checkNullPointerException(() -> Files.lines(null)); 360 checkNullPointerException(() -> Files.lines(null, US_ASCII)); 361 checkNullPointerException(() -> Files.lines(tmpfile, null)); 362 363 } finally { 364 Files.delete(tmpfile); 365 } 366 } 367 checkLines(Stream<String> s, List<String> expected)368 private void checkLines(Stream<String> s, List<String> expected) { 369 List<String> lines = s.collect(Collectors.toList()); 370 assertTrue(lines.size() == expected.size(), "Unexpected number of lines"); 371 assertTrue(lines.equals(expected), "Unexpected content"); 372 } 373 checkMalformedInputException(Stream<String> s)374 private void checkMalformedInputException(Stream<String> s) { 375 try { 376 List<String> lines = s.collect(Collectors.toList()); 377 fail("UncheckedIOException expected"); 378 } catch (UncheckedIOException ex) { 379 IOException cause = ex.getCause(); 380 assertTrue(cause instanceof MalformedInputException, 381 "MalformedInputException expected"); 382 } 383 } 384 checkNullPointerException(Callable<?> c)385 private void checkNullPointerException(Callable<?> c) { 386 try { 387 c.call(); 388 fail("NullPointerException expected"); 389 } catch (NullPointerException ignore) { 390 } catch (Exception e) { 391 fail(e + " not expected"); 392 } 393 } 394 testDirectoryIteratorException()395 public void testDirectoryIteratorException() throws IOException { 396 Path dir = testFolder.resolve("dir2"); 397 Path trigger = dir.resolve("DirectoryIteratorException"); 398 Files.createFile(trigger); 399 FaultyFileSystem.FaultyFSProvider fsp = FaultyFileSystem.FaultyFSProvider.getInstance(); 400 FaultyFileSystem fs = (FaultyFileSystem) fsp.newFileSystem(dir, null); 401 402 try { 403 fsp.setFaultyMode(false); 404 Path fakeRoot = fs.getRoot(); 405 try { 406 try (Stream<Path> s = Files.list(fakeRoot)) { 407 s.forEach(path -> assertEquals(path.getFileName().toString(), "DirectoryIteratorException")); 408 } 409 } catch (UncheckedIOException uioe) { 410 fail("Unexpected exception."); 411 } 412 413 fsp.setFaultyMode(true); 414 try { 415 try (DirectoryStream<Path> ds = Files.newDirectoryStream(fakeRoot)) { 416 Iterator<Path> itor = ds.iterator(); 417 while (itor.hasNext()) { 418 itor.next(); 419 } 420 } 421 fail("Shoule throw DirectoryIteratorException"); 422 } catch (DirectoryIteratorException die) { 423 } 424 425 try { 426 try (Stream<Path> s = Files.list(fakeRoot)) { 427 s.forEach(path -> fail("should not get here")); 428 } 429 } catch (UncheckedIOException uioe) { 430 assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException); 431 } catch (DirectoryIteratorException die) { 432 fail("Should have been converted into UncheckedIOException."); 433 } 434 } finally { 435 // Cleanup 436 if (fs != null) { 437 fs.close(); 438 } 439 Files.delete(trigger); 440 } 441 } 442 testUncheckedIOException()443 public void testUncheckedIOException() throws IOException { 444 Path triggerFile = testFolder.resolve(Paths.get("dir2", "IOException")); 445 Files.createFile(triggerFile); 446 Path triggerDir = testFolder.resolve(Paths.get("empty", "IOException")); 447 Files.createDirectories(triggerDir); 448 Files.createFile(triggerDir.resolve("file")); 449 FaultyFileSystem.FaultyFSProvider fsp = FaultyFileSystem.FaultyFSProvider.getInstance(); 450 FaultyFileSystem fs = (FaultyFileSystem) fsp.newFileSystem(testFolder, null); 451 452 try { 453 fsp.setFaultyMode(false); 454 Path fakeRoot = fs.getRoot(); 455 try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2"))) { 456 // only one file 457 s.forEach(path -> assertEquals(path.getFileName().toString(), "IOException")); 458 } 459 460 try (Stream<Path> s = Files.walk(fakeRoot.resolve("empty"))) { 461 String[] result = s.map(path -> path.getFileName().toString()) 462 .toArray(String[]::new); 463 // ordered as depth-first 464 assertEquals(result, new String[] { "empty", "IOException", "file"}); 465 } 466 467 fsp.setFaultyMode(true); 468 try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2"))) { 469 s.forEach(path -> fail("should have caused exception")); 470 } catch (UncheckedIOException uioe) { 471 assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException); 472 } 473 474 try (Stream<Path> s = Files.walk(fakeRoot.resolve("empty"))) { 475 String[] result = s.map(path -> path.getFileName().toString()) 476 .toArray(String[]::new); 477 fail("should not reach here due to IOException"); 478 } catch (UncheckedIOException uioe) { 479 assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException); 480 } 481 482 try (Stream<Path> s = Files.walk( 483 fakeRoot.resolve("empty").resolve("IOException"))) 484 { 485 String[] result = s.map(path -> path.getFileName().toString()) 486 .toArray(String[]::new); 487 fail("should not reach here due to IOException"); 488 } catch (IOException ioe) { 489 assertTrue(ioe instanceof FaultyFileSystem.FaultyException); 490 } catch (UncheckedIOException ex) { 491 fail("Top level should be repored as is"); 492 } 493 } finally { 494 // Cleanup 495 if (fs != null) { 496 fs.close(); 497 } 498 Files.delete(triggerFile); 499 TestUtil.removeAll(triggerDir); 500 } 501 } 502 testSecurityException()503 public void testSecurityException() throws IOException { 504 Path empty = testFolder.resolve("empty"); 505 Path triggerFile = Files.createFile(empty.resolve("SecurityException")); 506 Path sampleFile = Files.createDirectories(empty.resolve("sample")); 507 508 Path dir2 = testFolder.resolve("dir2"); 509 Path triggerDir = Files.createDirectories(dir2.resolve("SecurityException")); 510 Files.createFile(triggerDir.resolve("fileInSE")); 511 Path sample = Files.createFile(dir2.resolve("file")); 512 513 Path triggerLink = null; 514 Path linkTriggerDir = null; 515 Path linkTriggerFile = null; 516 if (supportsLinks) { 517 Path dir = testFolder.resolve("dir"); 518 triggerLink = Files.createSymbolicLink(dir.resolve("SecurityException"), empty); 519 linkTriggerDir = Files.createSymbolicLink(dir.resolve("lnDirSE"), triggerDir); 520 linkTriggerFile = Files.createSymbolicLink(dir.resolve("lnFileSE"), triggerFile); 521 } 522 523 FaultyFileSystem.FaultyFSProvider fsp = FaultyFileSystem.FaultyFSProvider.getInstance(); 524 FaultyFileSystem fs = (FaultyFileSystem) fsp.newFileSystem(testFolder, null); 525 526 try { 527 fsp.setFaultyMode(false); 528 Path fakeRoot = fs.getRoot(); 529 // validate setting 530 try (Stream<Path> s = Files.list(fakeRoot.resolve("empty"))) { 531 String[] result = s.map(path -> path.getFileName().toString()) 532 .toArray(String[]::new); 533 assertEqualsNoOrder(result, new String[] { "SecurityException", "sample" }); 534 } 535 536 try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir2"))) { 537 String[] result = s.map(path -> path.getFileName().toString()) 538 .toArray(String[]::new); 539 assertEqualsNoOrder(result, new String[] { "dir2", "SecurityException", "fileInSE", "file" }); 540 } 541 542 if (supportsLinks) { 543 try (Stream<Path> s = Files.list(fakeRoot.resolve("dir"))) { 544 String[] result = s.map(path -> path.getFileName().toString()) 545 .toArray(String[]::new); 546 assertEqualsNoOrder(result, new String[] { "d1", "f1", "lnDir2", "SecurityException", "lnDirSE", "lnFileSE" }); 547 } 548 } 549 550 // execute test 551 fsp.setFaultyMode(true); 552 // ignore file cause SecurityException 553 try (Stream<Path> s = Files.walk(fakeRoot.resolve("empty"))) { 554 String[] result = s.map(path -> path.getFileName().toString()) 555 .toArray(String[]::new); 556 assertEqualsNoOrder(result, new String[] { "empty", "sample" }); 557 } 558 // skip folder cause SecurityException 559 try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir2"))) { 560 String[] result = s.map(path -> path.getFileName().toString()) 561 .toArray(String[]::new); 562 assertEqualsNoOrder(result, new String[] { "dir2", "file" }); 563 } 564 565 if (supportsLinks) { 566 // not following links 567 try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir"))) { 568 String[] result = s.map(path -> path.getFileName().toString()) 569 .toArray(String[]::new); 570 assertEqualsNoOrder(result, new String[] { "dir", "d1", "f1", "lnDir2", "lnDirSE", "lnFileSE" }); 571 } 572 573 // following links 574 try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir"), FileVisitOption.FOLLOW_LINKS)) { 575 String[] result = s.map(path -> path.getFileName().toString()) 576 .toArray(String[]::new); 577 // ?? Should fileInSE show up? 578 // With FaultyFS, it does as no exception thrown for link to "SecurityException" with read on "lnXxxSE" 579 assertEqualsNoOrder(result, new String[] { "dir", "d1", "f1", "lnDir2", "file", "lnDirSE", "lnFileSE", "fileInSE" }); 580 } 581 } 582 583 // list instead of walk 584 try (Stream<Path> s = Files.list(fakeRoot.resolve("empty"))) { 585 String[] result = s.map(path -> path.getFileName().toString()) 586 .toArray(String[]::new); 587 assertEqualsNoOrder(result, new String[] { "sample" }); 588 } 589 try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2"))) { 590 String[] result = s.map(path -> path.getFileName().toString()) 591 .toArray(String[]::new); 592 assertEqualsNoOrder(result, new String[] { "file" }); 593 } 594 595 // root cause SecurityException should be reported 596 try (Stream<Path> s = Files.walk( 597 fakeRoot.resolve("dir2").resolve("SecurityException"))) 598 { 599 String[] result = s.map(path -> path.getFileName().toString()) 600 .toArray(String[]::new); 601 fail("should not reach here due to SecurityException"); 602 } catch (SecurityException se) { 603 assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException); 604 } 605 606 // Walk a file cause SecurityException, we should get SE 607 try (Stream<Path> s = Files.walk( 608 fakeRoot.resolve("dir").resolve("SecurityException"))) 609 { 610 String[] result = s.map(path -> path.getFileName().toString()) 611 .toArray(String[]::new); 612 fail("should not reach here due to SecurityException"); 613 } catch (SecurityException se) { 614 assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException); 615 } 616 617 // List a file cause SecurityException, we should get SE as cannot read attribute 618 try (Stream<Path> s = Files.list( 619 fakeRoot.resolve("dir2").resolve("SecurityException"))) 620 { 621 String[] result = s.map(path -> path.getFileName().toString()) 622 .toArray(String[]::new); 623 fail("should not reach here due to SecurityException"); 624 } catch (SecurityException se) { 625 assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException); 626 } 627 628 try (Stream<Path> s = Files.list( 629 fakeRoot.resolve("dir").resolve("SecurityException"))) 630 { 631 String[] result = s.map(path -> path.getFileName().toString()) 632 .toArray(String[]::new); 633 fail("should not reach here due to SecurityException"); 634 } catch (SecurityException se) { 635 assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException); 636 } 637 } finally { 638 // Cleanup 639 if (fs != null) { 640 fs.close(); 641 } 642 if (supportsLinks) { 643 Files.delete(triggerLink); 644 Files.delete(linkTriggerDir); 645 Files.delete(linkTriggerFile); 646 } 647 Files.delete(triggerFile); 648 Files.delete(sampleFile); 649 Files.delete(sample); 650 TestUtil.removeAll(triggerDir); 651 } 652 } 653 testConstructException()654 public void testConstructException() { 655 try (Stream<String> s = Files.lines(testFolder.resolve("notExist"), Charset.forName("UTF-8"))) { 656 s.forEach(l -> fail("File is not even exist!")); 657 } catch (IOException ioe) { 658 assertTrue(ioe instanceof NoSuchFileException); 659 } 660 } 661 testClosedStream()662 public void testClosedStream() throws IOException { 663 try (Stream<Path> s = Files.list(testFolder)) { 664 s.close(); 665 Object[] actual = s.sorted().toArray(); 666 fail("Operate on closed stream should throw IllegalStateException"); 667 } catch (IllegalStateException ex) { 668 // expected 669 } 670 671 try (Stream<Path> s = Files.walk(testFolder)) { 672 s.close(); 673 Object[] actual = s.sorted().toArray(); 674 fail("Operate on closed stream should throw IllegalStateException"); 675 } catch (IllegalStateException ex) { 676 // expected 677 } 678 679 try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, 680 (p, attr) -> true)) { 681 s.close(); 682 Object[] actual = s.sorted().toArray(); 683 fail("Operate on closed stream should throw IllegalStateException"); 684 } catch (IllegalStateException ex) { 685 // expected 686 } 687 } 688 testProcFile()689 public void testProcFile() throws IOException { 690 if (System.getProperty("os.name").equals("Linux")) { 691 Path path = Paths.get("/proc/cpuinfo"); 692 if (Files.exists(path)) { 693 String NEW_LINE = System.getProperty("line.separator"); 694 String s = 695 Files.lines(path).collect(Collectors.joining(NEW_LINE)); 696 if (s.length() == 0) { 697 fail("Files.lines(\"" + path + "\") returns no data"); 698 } 699 } 700 } 701 } 702 } 703