/*
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* @test
 * @bug 8006884 8019526
 * @library ..
 * @build PassThroughFileSystem FaultyFileSystem
 * @run testng StreamTest
 * @summary Unit test for java.nio.file.Files methods that return a Stream
 */

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.charset.MalformedInputException;
import java.nio.file.DirectoryIteratorException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystemLoopException;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.function.BiPredicate;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

@Test(groups = "unit")
public class StreamTest {
    /**
     * Default test folder
     * testFolder - empty
     *            - file
     *            - dir - d1
     *                  - f1
     *                  - lnDir2 (../dir2)
     *            - dir2
     *            - linkDir (./dir)
     *            - linkFile(./file)
     */
    static Path testFolder;
    static boolean supportsLinks;
    static Path[] level1;
    static Path[] all;
    static Path[] all_folowLinks;

    @BeforeClass
    void setupTestFolder() throws IOException {
        testFolder = TestUtil.createTemporaryDirectory();
        supportsLinks = TestUtil.supportsLinks(testFolder);
        TreeSet<Path> set = new TreeSet<>();

        // Level 1
        Path empty = testFolder.resolve("empty");
        Path file = testFolder.resolve("file");
        Path dir = testFolder.resolve("dir");
        Path dir2 = testFolder.resolve("dir2");
        Files.createDirectory(empty);
        Files.createFile(file);
        Files.createDirectory(dir);
        Files.createDirectory(dir2);
        set.add(empty);
        set.add(file);
        set.add(dir);
        set.add(dir2);
        if (supportsLinks) {
            Path tmp = testFolder.resolve("linkDir");
            Files.createSymbolicLink(tmp, dir);
            set.add(tmp);
            tmp = testFolder.resolve("linkFile");
            Files.createSymbolicLink(tmp, file);
            set.add(tmp);
        }
        level1 = set.toArray(new Path[0]);

        // Level 2
        Path tmp = dir.resolve("d1");
        Files.createDirectory(tmp);
        set.add(tmp);
        tmp = dir.resolve("f1");
        Files.createFile(tmp);
        set.add(tmp);
        if (supportsLinks) {
            tmp = dir.resolve("lnDir2");
            Files.createSymbolicLink(tmp, dir2);
            set.add(tmp);
        }
        // walk include starting folder
        set.add(testFolder);
        all = set.toArray(new Path[0]);

        // Follow links
        if (supportsLinks) {
            tmp = testFolder.resolve("linkDir");
            set.add(tmp.resolve("d1"));
            set.add(tmp.resolve("f1"));
            tmp = tmp.resolve("lnDir2");
            set.add(tmp);
        }
        all_folowLinks = set.toArray(new Path[0]);
    }

    @AfterClass
    void cleanupTestFolder() throws IOException {
        TestUtil.removeAll(testFolder);
    }

    public void testBasic() {
        try (Stream<Path> s = Files.list(testFolder)) {
            Object[] actual = s.sorted().toArray();
            assertEquals(actual, level1);
        } catch (IOException ioe) {
            fail("Unexpected IOException");
        }

        try (Stream<Path> s = Files.list(testFolder.resolve("empty"))) {
            int count = s.mapToInt(p -> 1).reduce(0, Integer::sum);
            assertEquals(count, 0, "Expect empty stream.");
        } catch (IOException ioe) {
            fail("Unexpected IOException");
        }
    }

    public void testWalk() {
        try (Stream<Path> s = Files.walk(testFolder)) {
            Object[] actual = s.sorted().toArray();
            assertEquals(actual, all);
        } catch (IOException ioe) {
            fail("Unexpected IOException");
        }
    }

    public void testWalkOneLevel() {
        try (Stream<Path> s = Files.walk(testFolder, 1)) {
            Object[] actual = s.filter(path -> ! path.equals(testFolder))
                               .sorted()
                               .toArray();
            assertEquals(actual, level1);
        } catch (IOException ioe) {
            fail("Unexpected IOException");
        }
    }

    public void testWalkFollowLink() {
        // If link is not supported, the directory structure won't have link.
        // We still want to test the behavior with FOLLOW_LINKS option.
        try (Stream<Path> s = Files.walk(testFolder, FileVisitOption.FOLLOW_LINKS)) {
            Object[] actual = s.sorted().toArray();
            assertEquals(actual, all_folowLinks);
        } catch (IOException ioe) {
            fail("Unexpected IOException");
        }
    }

    private void validateFileSystemLoopException(Path start, Path... causes) {
        try (Stream<Path> s = Files.walk(start, FileVisitOption.FOLLOW_LINKS)) {
            try {
                int count = s.mapToInt(p -> 1).reduce(0, Integer::sum);
                fail("Should got FileSystemLoopException, but got " + count + "elements.");
            } catch (UncheckedIOException uioe) {
                IOException ioe = uioe.getCause();
                if (ioe instanceof FileSystemLoopException) {
                    FileSystemLoopException fsle = (FileSystemLoopException) ioe;
                    boolean match = false;
                    for (Path cause: causes) {
                        if (fsle.getFile().equals(cause.toString())) {
                            match = true;
                            break;
                        }
                    }
                    assertTrue(match);
                } else {
                    fail("Unexpected UncheckedIOException cause " + ioe.toString());
                }
            }
        } catch(IOException ex) {
            fail("Unexpected IOException " + ex);
        }
    }

    public void testWalkFollowLinkLoop() {
        if (!supportsLinks) {
            return;
        }

        // Loops.
        try {
            Path dir = testFolder.resolve("dir");
            Path linkdir = testFolder.resolve("linkDir");
            Path d1 = dir.resolve("d1");
            Path cause = d1.resolve("lnSelf");
            Files.createSymbolicLink(cause, d1);

            // loop in descendant.
            validateFileSystemLoopException(dir, cause);
            // loop in self
            validateFileSystemLoopException(d1, cause);
            // start from other place via link
            validateFileSystemLoopException(linkdir,
                    linkdir.resolve(Paths.get("d1", "lnSelf")));
            Files.delete(cause);

            // loop to parent.
            cause = d1.resolve("lnParent");
            Files.createSymbolicLink(cause, dir);

            // loop should be detected at test/dir/d1/lnParent/d1
            validateFileSystemLoopException(d1, cause.resolve("d1"));
            // loop should be detected at link
            validateFileSystemLoopException(dir, cause);
            // loop should be detected at test/linkdir/d1/lnParent
            // which is test/dir we have visited via test/linkdir
            validateFileSystemLoopException(linkdir,
                    linkdir.resolve(Paths.get("d1", "lnParent")));
            Files.delete(cause);

            // cross loop
            Path dir2 = testFolder.resolve("dir2");
            cause = dir2.resolve("lnDir");
            Files.createSymbolicLink(cause, dir);
            validateFileSystemLoopException(dir,
                    dir.resolve(Paths.get("lnDir2", "lnDir")));
            validateFileSystemLoopException(dir2,
                    dir2.resolve(Paths.get("lnDir", "lnDir2")));
            validateFileSystemLoopException(linkdir,
                    linkdir.resolve(Paths.get("lnDir2", "lnDir")));
        } catch(IOException ioe) {
            fail("Unexpected IOException " + ioe);
        }
    }

    private static class PathBiPredicate implements BiPredicate<Path, BasicFileAttributes> {
        private final BiPredicate<Path, BasicFileAttributes> pred;
        private final Set<Path> visited = new TreeSet<Path>();

        PathBiPredicate(BiPredicate<Path, BasicFileAttributes> pred) {
            this.pred = Objects.requireNonNull(pred);
        }

        public boolean test(Path path, BasicFileAttributes attrs) {
            visited.add(path);
            return pred.test(path, attrs);
        }

        public Path[] visited() {
            return visited.toArray(new Path[0]);
        }
    }

    public void testFind() throws IOException {
        PathBiPredicate pred = new PathBiPredicate((path, attrs) -> true);

        try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) {
            Set<Path> result = s.collect(Collectors.toCollection(TreeSet::new));
            assertEquals(pred.visited(), all);
            assertEquals(result.toArray(new Path[0]), pred.visited());
        }

        pred = new PathBiPredicate((path, attrs) -> attrs.isSymbolicLink());
        try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) {
            s.forEach(path -> assertTrue(Files.isSymbolicLink(path)));
            assertEquals(pred.visited(), all);
        }

        pred = new PathBiPredicate((path, attrs) ->
            path.getFileName().toString().startsWith("e"));
        try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) {
            s.forEach(path -> assertEquals(path.getFileName().toString(), "empty"));
            assertEquals(pred.visited(), all);
        }

        pred = new PathBiPredicate((path, attrs) ->
            path.getFileName().toString().startsWith("l") && attrs.isRegularFile());
        try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE, pred)) {
            s.forEach(path -> fail("Expect empty stream"));
            assertEquals(pred.visited(), all);
        }
    }

    // Test borrowed from BytesAndLines
    public void testLines() throws IOException {
        final Charset US_ASCII = Charset.forName("US-ASCII");
        Path tmpfile = Files.createTempFile("blah", "txt");

        try {
            // zero lines
            assertTrue(Files.size(tmpfile) == 0, "File should be empty");
            try (Stream<String> s = Files.lines(tmpfile)) {
                checkLines(s, Collections.emptyList());
            }
            try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) {
                checkLines(s, Collections.emptyList());
            }

            // one line
            List<String> oneLine = Arrays.asList("hi");
            Files.write(tmpfile, oneLine, US_ASCII);
            try (Stream<String> s = Files.lines(tmpfile)) {
                checkLines(s, oneLine);
            }
            try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) {
                checkLines(s, oneLine);
            }

            // two lines using platform's line separator
            List<String> twoLines = Arrays.asList("hi", "there");
            Files.write(tmpfile, twoLines, US_ASCII);
            try (Stream<String> s = Files.lines(tmpfile)) {
                checkLines(s, twoLines);
            }
            try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) {
                checkLines(s, twoLines);
            }

            // MalformedInputException
            byte[] bad = { (byte)0xff, (byte)0xff };
            Files.write(tmpfile, bad);
            try (Stream<String> s = Files.lines(tmpfile)) {
                checkMalformedInputException(s);
            }
            try (Stream<String> s = Files.lines(tmpfile, US_ASCII)) {
                checkMalformedInputException(s);
            }

            // NullPointerException
            checkNullPointerException(() -> Files.lines(null));
            checkNullPointerException(() -> Files.lines(null, US_ASCII));
            checkNullPointerException(() -> Files.lines(tmpfile, null));

        } finally {
            Files.delete(tmpfile);
        }
    }

    private void checkLines(Stream<String> s, List<String> expected) {
        List<String> lines = s.collect(Collectors.toList());
        assertTrue(lines.size() == expected.size(), "Unexpected number of lines");
        assertTrue(lines.equals(expected), "Unexpected content");
    }

    private void checkMalformedInputException(Stream<String> s) {
        try {
            List<String> lines = s.collect(Collectors.toList());
            fail("UncheckedIOException expected");
        } catch (UncheckedIOException ex) {
            IOException cause = ex.getCause();
            assertTrue(cause instanceof MalformedInputException,
                "MalformedInputException expected");
        }
    }

    private void checkNullPointerException(Callable<?> c) {
        try {
            c.call();
            fail("NullPointerException expected");
        } catch (NullPointerException ignore) {
        } catch (Exception e) {
            fail(e + " not expected");
        }
    }

    public void testDirectoryIteratorException() throws IOException {
        Path dir = testFolder.resolve("dir2");
        Path trigger = dir.resolve("DirectoryIteratorException");
        Files.createFile(trigger);
        FaultyFileSystem.FaultyFSProvider fsp = FaultyFileSystem.FaultyFSProvider.getInstance();
        FaultyFileSystem fs = (FaultyFileSystem) fsp.newFileSystem(dir, null);

        try {
            fsp.setFaultyMode(false);
            Path fakeRoot = fs.getRoot();
            try {
                try (Stream<Path> s = Files.list(fakeRoot)) {
                    s.forEach(path -> assertEquals(path.getFileName().toString(), "DirectoryIteratorException"));
                }
            } catch (UncheckedIOException uioe) {
                fail("Unexpected exception.");
            }

            fsp.setFaultyMode(true);
            try {
                try (DirectoryStream<Path> ds = Files.newDirectoryStream(fakeRoot)) {
                    Iterator<Path> itor = ds.iterator();
                    while (itor.hasNext()) {
                        itor.next();
                    }
                }
                fail("Shoule throw DirectoryIteratorException");
            } catch (DirectoryIteratorException die) {
            }

            try {
                try (Stream<Path> s = Files.list(fakeRoot)) {
                    s.forEach(path -> fail("should not get here"));
                }
            } catch (UncheckedIOException uioe) {
                assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException);
            } catch (DirectoryIteratorException die) {
                fail("Should have been converted into UncheckedIOException.");
            }
        } finally {
            // Cleanup
            if (fs != null) {
                fs.close();
            }
            Files.delete(trigger);
        }
    }

    public void testUncheckedIOException() throws IOException {
        Path triggerFile = testFolder.resolve(Paths.get("dir2", "IOException"));
        Files.createFile(triggerFile);
        Path triggerDir = testFolder.resolve(Paths.get("empty", "IOException"));
        Files.createDirectories(triggerDir);
        Files.createFile(triggerDir.resolve("file"));
        FaultyFileSystem.FaultyFSProvider fsp = FaultyFileSystem.FaultyFSProvider.getInstance();
        FaultyFileSystem fs = (FaultyFileSystem) fsp.newFileSystem(testFolder, null);

        try {
            fsp.setFaultyMode(false);
            Path fakeRoot = fs.getRoot();
            try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2"))) {
                // only one file
                s.forEach(path -> assertEquals(path.getFileName().toString(), "IOException"));
            }

            try (Stream<Path> s = Files.walk(fakeRoot.resolve("empty"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                // ordered as depth-first
                assertEquals(result, new String[] { "empty", "IOException", "file"});
            }

            fsp.setFaultyMode(true);
            try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2"))) {
                s.forEach(path -> fail("should have caused exception"));
            } catch (UncheckedIOException uioe) {
                assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException);
            }

            try (Stream<Path> s = Files.walk(fakeRoot.resolve("empty"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                fail("should not reach here due to IOException");
            } catch (UncheckedIOException uioe) {
                assertTrue(uioe.getCause() instanceof FaultyFileSystem.FaultyException);
            }

            try (Stream<Path> s = Files.walk(
                fakeRoot.resolve("empty").resolve("IOException")))
            {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                fail("should not reach here due to IOException");
            } catch (IOException ioe) {
                assertTrue(ioe instanceof FaultyFileSystem.FaultyException);
            } catch (UncheckedIOException ex) {
                fail("Top level should be repored as is");
            }
         } finally {
            // Cleanup
            if (fs != null) {
                fs.close();
            }
            Files.delete(triggerFile);
            TestUtil.removeAll(triggerDir);
        }
    }

    public void testSecurityException() throws IOException {
        Path empty = testFolder.resolve("empty");
        Path triggerFile = Files.createFile(empty.resolve("SecurityException"));
        Path sampleFile = Files.createDirectories(empty.resolve("sample"));

        Path dir2 = testFolder.resolve("dir2");
        Path triggerDir = Files.createDirectories(dir2.resolve("SecurityException"));
        Files.createFile(triggerDir.resolve("fileInSE"));
        Path sample = Files.createFile(dir2.resolve("file"));

        Path triggerLink = null;
        Path linkTriggerDir = null;
        Path linkTriggerFile = null;
        if (supportsLinks) {
            Path dir = testFolder.resolve("dir");
            triggerLink = Files.createSymbolicLink(dir.resolve("SecurityException"), empty);
            linkTriggerDir = Files.createSymbolicLink(dir.resolve("lnDirSE"), triggerDir);
            linkTriggerFile = Files.createSymbolicLink(dir.resolve("lnFileSE"), triggerFile);
        }

        FaultyFileSystem.FaultyFSProvider fsp = FaultyFileSystem.FaultyFSProvider.getInstance();
        FaultyFileSystem fs = (FaultyFileSystem) fsp.newFileSystem(testFolder, null);

        try {
            fsp.setFaultyMode(false);
            Path fakeRoot = fs.getRoot();
            // validate setting
            try (Stream<Path> s = Files.list(fakeRoot.resolve("empty"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                assertEqualsNoOrder(result, new String[] { "SecurityException", "sample" });
            }

            try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir2"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                assertEqualsNoOrder(result, new String[] { "dir2", "SecurityException", "fileInSE", "file" });
            }

            if (supportsLinks) {
                try (Stream<Path> s = Files.list(fakeRoot.resolve("dir"))) {
                    String[] result = s.map(path -> path.getFileName().toString())
                                       .toArray(String[]::new);
                    assertEqualsNoOrder(result, new String[] { "d1", "f1", "lnDir2", "SecurityException", "lnDirSE", "lnFileSE" });
                }
            }

            // execute test
            fsp.setFaultyMode(true);
            // ignore file cause SecurityException
            try (Stream<Path> s = Files.walk(fakeRoot.resolve("empty"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                assertEqualsNoOrder(result, new String[] { "empty", "sample" });
            }
            // skip folder cause SecurityException
            try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir2"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                assertEqualsNoOrder(result, new String[] { "dir2", "file" });
            }

            if (supportsLinks) {
                // not following links
                try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir"))) {
                    String[] result = s.map(path -> path.getFileName().toString())
                                       .toArray(String[]::new);
                    assertEqualsNoOrder(result, new String[] { "dir", "d1", "f1", "lnDir2", "lnDirSE", "lnFileSE" });
                }

                // following links
                try (Stream<Path> s = Files.walk(fakeRoot.resolve("dir"), FileVisitOption.FOLLOW_LINKS)) {
                    String[] result = s.map(path -> path.getFileName().toString())
                                       .toArray(String[]::new);
                    // ?? Should fileInSE show up?
                    // With FaultyFS, it does as no exception thrown for link to "SecurityException" with read on "lnXxxSE"
                    assertEqualsNoOrder(result, new String[] { "dir", "d1", "f1", "lnDir2", "file", "lnDirSE", "lnFileSE", "fileInSE" });
                }
            }

            // list instead of walk
            try (Stream<Path> s = Files.list(fakeRoot.resolve("empty"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                assertEqualsNoOrder(result, new String[] { "sample" });
            }
            try (Stream<Path> s = Files.list(fakeRoot.resolve("dir2"))) {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                assertEqualsNoOrder(result, new String[] { "file" });
            }

            // root cause SecurityException should be reported
            try (Stream<Path> s = Files.walk(
                fakeRoot.resolve("dir2").resolve("SecurityException")))
            {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                fail("should not reach here due to SecurityException");
            } catch (SecurityException se) {
                assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
            }

            // Walk a file cause SecurityException, we should get SE
            try (Stream<Path> s = Files.walk(
                fakeRoot.resolve("dir").resolve("SecurityException")))
            {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                fail("should not reach here due to SecurityException");
            } catch (SecurityException se) {
                assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
            }

            // List a file cause SecurityException, we should get SE as cannot read attribute
            try (Stream<Path> s = Files.list(
                fakeRoot.resolve("dir2").resolve("SecurityException")))
            {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                fail("should not reach here due to SecurityException");
            } catch (SecurityException se) {
                assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
            }

            try (Stream<Path> s = Files.list(
                fakeRoot.resolve("dir").resolve("SecurityException")))
            {
                String[] result = s.map(path -> path.getFileName().toString())
                                   .toArray(String[]::new);
                fail("should not reach here due to SecurityException");
            } catch (SecurityException se) {
                assertTrue(se.getCause() instanceof FaultyFileSystem.FaultyException);
            }
         } finally {
            // Cleanup
            if (fs != null) {
                fs.close();
            }
            if (supportsLinks) {
                Files.delete(triggerLink);
                Files.delete(linkTriggerDir);
                Files.delete(linkTriggerFile);
            }
            Files.delete(triggerFile);
            Files.delete(sampleFile);
            Files.delete(sample);
            TestUtil.removeAll(triggerDir);
        }
    }

    public void testConstructException() {
        try (Stream<String> s = Files.lines(testFolder.resolve("notExist"), Charset.forName("UTF-8"))) {
            s.forEach(l -> fail("File is not even exist!"));
        } catch (IOException ioe) {
            assertTrue(ioe instanceof NoSuchFileException);
        }
    }

    public void testClosedStream() throws IOException {
        try (Stream<Path> s = Files.list(testFolder)) {
            s.close();
            Object[] actual = s.sorted().toArray();
            fail("Operate on closed stream should throw IllegalStateException");
        } catch (IllegalStateException ex) {
            // expected
        }

        try (Stream<Path> s = Files.walk(testFolder)) {
            s.close();
            Object[] actual = s.sorted().toArray();
            fail("Operate on closed stream should throw IllegalStateException");
        } catch (IllegalStateException ex) {
            // expected
        }

        try (Stream<Path> s = Files.find(testFolder, Integer.MAX_VALUE,
                    (p, attr) -> true)) {
            s.close();
            Object[] actual = s.sorted().toArray();
            fail("Operate on closed stream should throw IllegalStateException");
        } catch (IllegalStateException ex) {
            // expected
        }
    }
}
