Path: blob/master/test/jdk/java/nio/file/Files/walkFileTree/FindTest.java
41155 views
/*1* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 4313887 690773726* @summary Tests that walkFileTree is consistent with the native find program27* @requires (os.family != "windows")28* @library /test/lib29* @build jdk.test.lib.Utils30* jdk.test.lib.Asserts31* jdk.test.lib.JDKToolFinder32* jdk.test.lib.JDKToolLauncher33* jdk.test.lib.Platform34* jdk.test.lib.process.*35* CreateFileTree36* @run testng/othervm -Djava.io.tmpdir=. FindTest37*/3839import java.io.IOException;40import java.nio.file.FileSystemLoopException;41import java.nio.file.FileVisitOption;42import java.nio.file.FileVisitResult;43import java.nio.file.FileVisitor;44import java.nio.file.Files;45import java.nio.file.Path;46import java.nio.file.attribute.BasicFileAttributes;47import java.util.ArrayList;48import java.util.Arrays;49import java.util.HashSet;50import java.util.List;51import java.util.Random;52import java.util.Set;53import java.util.stream.Collectors;5455import jdk.test.lib.process.OutputAnalyzer;56import jdk.test.lib.process.ProcessTools;5758import org.testng.annotations.BeforeClass;59import org.testng.annotations.Test;6061import static org.testng.Assert.assertEquals;62import static org.testng.Assert.assertTrue;6364public class FindTest {6566private static final Random rand = new Random();67private static final boolean isAIX = System.getProperty("os.name").equals("AIX");68private static Path top;69private static String TOP;7071@BeforeClass72public static void createFileTree() throws Exception {73top = CreateFileTree.create();74TOP = top.toAbsolutePath().toString();75}7677@Test78public void printTreeTest() throws Throwable {79// print the file tree and compare output with find(1)80assertOutputEquals(printFileTree(top), runFind("find", TOP));81}8283@Test84public void printTreeFollowLinkTest() throws Throwable {85// print the file tree, following links, and compare output with find(1).8687// On AIX "find -follow" may core dump on recursive links without '-L'88// see: http://www-01.ibm.com/support/docview.wss?uid=isg1IV2814389String[] cmds = isAIX90? new String[]{"find", "-L", TOP, "-follow"}91: new String[]{"find", TOP, "-follow"};92OutputAnalyzer expected = runFind(cmds);9394// Some versions of find(1) output cycles (sym links to ancestor95// directories), other versions do not. For that reason we run96// PrintFileTree with the -printCycles option when the output without97// this option differs to find(1).98try {99assertOutputEquals(printFileTree(top, "-follow"), expected);100} catch (AssertionError x) {101assertOutputEquals(printFileTree(top, "-follow", "-printCycles"), expected);102}103}104105private void assertOutputEquals(List<String> actual, OutputAnalyzer expected)106throws IOException {107List<String> expectedList = Arrays.asList(expected.getStdout()108.split(System.lineSeparator()));109assertEquals(actual.size(), expectedList.size());110assertTrue(actual.removeAll(expectedList));111}112113private OutputAnalyzer runFind(String... cmds) throws Throwable {114return ProcessTools.executeCommand(cmds);115}116117/**118* Invokes Files.walkFileTree to traverse a file tree and prints119* each of the directories and files. The -follow option causes symbolic120* links to be followed and the -printCycles option will print links121* where the target of the link is an ancestor directory.122*/123private static List<String> printFileTree(Path dir, String... opts) throws Exception {124List<Path> fileTreeList = new ArrayList<>();125126List<String> optsList = Arrays.asList(opts);127boolean followLinks = optsList.contains("-follow");128boolean reportCycles = optsList.contains("-printCycles");129130Set<FileVisitOption> options = new HashSet<>();131if (followLinks)132options.add(FileVisitOption.FOLLOW_LINKS);133134Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<Path>() {135@Override136public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {137fileTreeList.add(dir);138return FileVisitResult.CONTINUE;139}140@Override141public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {142fileTreeList.add(file);143return FileVisitResult.CONTINUE;144}145@Override146public FileVisitResult postVisitDirectory(Path dir, IOException exc)147throws IOException148{149if (exc != null)150throw exc;151return FileVisitResult.CONTINUE;152}153@Override154public FileVisitResult visitFileFailed(Path file, IOException exc)155throws IOException156{157if (followLinks && (exc instanceof FileSystemLoopException)) {158if (reportCycles)159fileTreeList.add(file);160return FileVisitResult.CONTINUE;161} else {162throw exc;163}164}165});166167return fileTreeList.stream()168.map(f -> f.toAbsolutePath().toString())169.collect(Collectors.toCollection(ArrayList::new));170}171}172173174