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