1 /* 2 * Copyright (c) 2012, 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 function test for Files.list()/find()/walk()/lines() 27 * @library /sqeutil 28 * @(#) FilesLambdaTest.java 29 * @author Tristan Yan 30 * @run testng/othervm FilesLambdaTest 31 */ 32 33 import java.io.BufferedReader; 34 import java.io.BufferedWriter; 35 import java.io.IOException; 36 import java.nio.charset.Charset; 37 import java.nio.file.FileVisitResult; 38 import java.nio.file.Files; 39 import java.nio.file.LinkOption; 40 import java.nio.file.NotDirectoryException; 41 import java.nio.file.Path; 42 import java.nio.file.Paths; 43 import java.nio.file.SimpleFileVisitor; 44 import java.nio.file.attribute.BasicFileAttributes; 45 import java.util.ArrayList; 46 import java.util.Collections; 47 import java.util.List; 48 import java.util.Random; 49 import java.util.function.Consumer; 50 import java.util.stream.Collectors; 51 import java.util.stream.Stream; 52 import static org.testng.Assert.*; 53 import org.testng.annotations.AfterClass; 54 import org.testng.annotations.BeforeClass; 55 import org.testng.annotations.Test; 56 57 public class FilesLambdaTest { 58 private static final Random rand = new Random(System.nanoTime()); 59 60 private static final String TEST_SRC = System.getProperty("test.src"); 61 62 private static final String ROOT_NAME = "FilesLambdaTest" + System.nanoTime(); 63 64 private static final String LINES_TEST_FILE = "lines" + System.nanoTime(); 65 66 private static final int MAX_FILES_NUMBER = 1 << 6; 67 68 private static final Charset UTF8 = Charset.forName("UTF-8"); 69 70 private final static int MIN_LEN = 1 << 2; 71 72 private final static int MAX_LEN = 1 << 8; 73 74 private final static int LINES_NUM = 1 << 8; 75 76 private static final String[][] folders = { 77 {"A01"}, 78 {"A01", "AA02"}, 79 {"A01", "AB02"}, 80 {"A01", "AC02"}, 81 {"B01"}, 82 {"B01", "BA02"}, 83 {"B01", "BA02", "BAA03"}, 84 {"B01", "BA02", "BAA03", "BAAA04", "BAAAA05", "BAAAAA06", "BAAAAAA07", 85 "BAAAAAAA08", "BAAAAAAAA09", "BAAAAAAAAA10", "BAAAAAAAAAA11"}, 86 {"C01"}, 87 {"C01", "CA02"}, 88 {"C01", "CD02"}, 89 {"D01", "DA02", "DAA03", "DAAA04", "DAAAA05", "DAAAAA06", "DAAAAAA07"}, 90 {"E01"}, 91 {"E01", "EA02"}, 92 {"E01", "EB02", "EBB03"}, 93 {"E01", "EC02", "ECC03", "ECCC04"}, 94 {"E01", "ED02", "EDD03", "EDDD04", "EDDDD05"}, 95 {"E01", "EE02", "EEE03", "EEEE04", "EEEEE05", "EEEEEE06"}, 96 {"E01", "EF02", "EFF03", "EFFF04", "EFFFF05", "EFFFFF06"}, 97 {"E01", "EG02", "EGG03", "EGGG04", "EGGGG05", "EGGGGG06", "EGGGGGG07"}, 98 {"E01", "EH02", "EHH03", "EHHH04", "EHHHH05", "EHHHHH06", "EHHHHHH07", 99 "EHHHHHHH08"}, 100 {"E01", "EI02", "EII03", "EIII04", "EIIII05", "EIIIII06", "EIIIIII07", 101 "EIIIIIII08", "EIIIIIIII09"}, 102 {"E01", "EJ02", "EJJ03", "EJJJ04", "EJJJJ05", "EJJJJJ06", "EJJJJJJ07", 103 "EJJJJJJJ08", "EJJJJJJJJ09", "EJJJJJJJJJ10"}, 104 {"E01", "EK02", "EKK03", "EKKK04", "EKKKK05", "EKKKKK06", "EKKKKKK07", 105 "EKKKKKKK08", "EKKKKKKKK09", "EKKKKKKKKK10", "EJJJJJJJJJJ11"} 106 }; 107 108 private Path root; 109 110 private Path testFile; 111 112 private Path notExistPath; 113 114 final Consumer<Path> writeReverseWithLink = path -> { 115 int filesCount = rand.nextInt(MAX_FILES_NUMBER); 116 for(int count = 0; count < filesCount; count++) { 117 String fileName = String.valueOf(rand.nextLong()); 118 Path file = path.resolve(fileName); 119 String linkName = String.valueOf(rand.nextLong()); 120 Path link = path.resolve(linkName); 121 try (BufferedWriter writer 122 = Files.newBufferedWriter(Files.createFile(file), UTF8)) { 123 writer.write(new StringBuilder(fileName).reverse().toString(), 124 0, fileName.length()); 125 Files.createSymbolicLink(link, file); 126 } catch (IOException ex) { 127 throw new RuntimeException(ex); 128 } 129 } 130 }; 131 132 @BeforeClass 133 public void filesSetUp() throws IOException { 134 List<Path> paths = new ArrayList<>(); 135 root = Paths.get(TEST_SRC, ROOT_NAME); 136 paths.add(Files.createDirectory(root)); 137 for(int i = 0; i < folders.length; i++ ) { 138 String[] toBeCreated = folders[i]; 139 Path folder = Paths.get(ROOT_NAME, toBeCreated); 140 paths.add(Files.createDirectories(folder)); 141 } 142 paths.forEach(writeReverseWithLink); 143 144 testFile = Paths.get(LINES_TEST_FILE); 145 try (BufferedWriter writer 146 = Files.newBufferedWriter(Files.createFile(testFile), UTF8)) { 147 for(int i = 0; i< LINES_NUM; i++) { 148 String line = StringUtilities.randomString(MAX_LEN, MIN_LEN); 149 writer.write(line, 0, line.length()); 150 } 151 } catch (IOException ex) { 152 throw new RuntimeException(ex); 153 } 154 155 String NOT_EXIST = "NOT_EXIST"; 156 notExistPath = Paths.get(TEST_SRC, NOT_EXIST); 157 } 158 159 @AfterClass 160 public void filesTearDown() throws IOException { 161 if(root != null) { 162 Files.walkFileTree(root, new SimpleFileVisitor<Path>() { 163 @Override 164 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 165 throws IOException { 166 Files.delete(file); 167 return FileVisitResult.CONTINUE; 168 } 169 @Override 170 public FileVisitResult postVisitDirectory(Path dir, IOException exc) 171 throws IOException{ 172 Files.delete(dir); 173 return FileVisitResult.CONTINUE; 174 } 175 }); 176 } 177 if(testFile != null) { 178 Files.delete(testFile); 179 } 180 } 181 182 @Test 183 public void testFilesList() throws IOException { 184 checkFilesList(root); 185 } 186 187 @Test 188 public void testWalk() throws IOException{ 189 String[] dir = folders[rand.nextInt(folders.length)]; 190 Path walkFolder = Paths.get(ROOT_NAME, dir); 191 final int maxDepth = rand.nextInt(11); 192 List<Path> expectedFullFileList = new ArrayList<>(); 193 List<Path> expectedMaxDepthFileList = new ArrayList<>(); 194 195 List<Path> expectedFullSymList = new ArrayList<>(); 196 List<Path> expectedMaxDepthSymList = new ArrayList<>(); 197 198 List<Path> expectedFullDirList = new ArrayList<>(); 199 List<Path> expectedMaxDepthDirList = new ArrayList<>(); 200 201 Files.walkFileTree(walkFolder, new SimpleFileVisitor<Path>() { 202 @Override 203 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 204 throws IOException { 205 if (walkFolder.relativize(file).getNameCount() <= maxDepth) { 206 expectedMaxDepthFileList.add(file); 207 if(Files.isSymbolicLink(file)) { 208 expectedMaxDepthSymList.add(file); 209 } 210 } 211 expectedFullFileList.add(file); 212 if(Files.isSymbolicLink(file)) { 213 expectedFullSymList.add(file); 214 } 215 return FileVisitResult.CONTINUE; 216 } 217 @Override 218 public FileVisitResult postVisitDirectory(Path dir, IOException exc) 219 throws IOException{ 220 if (walkFolder.relativize(dir).getNameCount() <= maxDepth 221 || walkFolder.equals(dir)) { 222 expectedMaxDepthDirList.add(dir); 223 } 224 expectedFullDirList.add(dir); 225 return FileVisitResult.CONTINUE; 226 } 227 }); 228 Collections.sort(expectedFullFileList); 229 Collections.sort(expectedMaxDepthFileList); 230 Collections.sort(expectedFullSymList); 231 Collections.sort(expectedMaxDepthSymList); 232 Collections.sort(expectedFullDirList); 233 Collections.sort(expectedMaxDepthDirList); 234 235 assertEquals(expectedMaxDepthFileList, 236 Files.walk(walkFolder, maxDepth).filter(p -> !Files.isDirectory(p)). 237 sorted().collect(Collectors.toList())); 238 assertEquals(expectedMaxDepthSymList, 239 Files.walk(walkFolder, maxDepth).filter(p -> Files.isSymbolicLink(p)). 240 sorted().collect(Collectors.toList())); 241 assertEquals(expectedMaxDepthDirList, 242 Files.walk(walkFolder, maxDepth).filter(p -> Files.isDirectory(p)). 243 sorted().collect(Collectors.toList())); 244 assertEquals(expectedFullFileList, 245 Files.walk(walkFolder).filter(p -> !Files.isDirectory(p)). 246 sorted().collect(Collectors.toList())); 247 assertEquals(expectedFullSymList, 248 Files.walk(walkFolder).filter(p -> Files.isSymbolicLink(p)). 249 sorted().collect(Collectors.toList())); 250 assertEquals(expectedFullDirList, 251 Files.walk(walkFolder).filter(p -> Files.isDirectory(p)). 252 sorted().collect(Collectors.toList())); 253 } 254 255 @Test 256 public void testFind() throws IOException{ 257 String[] dir = folders[rand.nextInt(folders.length)]; 258 Path walkFolder = Paths.get(ROOT_NAME, dir); 259 String walkFoderName = dir[dir.length - 1]; 260 261 int walkFolderDepth = Integer.parseInt(walkFoderName.substring(walkFoderName.length() - 2)); 262 int maxDepth = rand.nextInt(11); 263 Stream<Path> stream 264 = Files.find(walkFolder, maxDepth, (p,bfa) -> Files.isSymbolicLink(p)); 265 stream.forEach(p -> { 266 assertTrue(Files.isSymbolicLink(p)); 267 assertFalse(Files.isDirectory(p)); 268 assertFalse(Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)); 269 String parentName = p.getParent().toFile().getName(); 270 int depth = Integer.parseInt(parentName.substring(parentName.length() - 2)); 271 assertTrue(depth - walkFolderDepth < maxDepth); 272 }); 273 274 assertEquals(Files.find(walkFolder, maxDepth, (p,bfa) -> Files.isSymbolicLink(p)).toArray(), 275 Files.find(walkFolder, maxDepth, (p,bfa) -> bfa.isSymbolicLink()).toArray()); 276 } 277 278 @Test 279 public void testLines() throws IOException{ 280 Stream<String> stream = Files.lines(testFile, UTF8); 281 List<String> lines = Files.readAllLines(testFile, UTF8); 282 assertEquals(lines, stream.collect(Collectors.toList())); 283 } 284 285 @Test(expectedExceptions = IOException.class) 286 public void testListNoReadAccess() throws IOException{ 287 Files.list(notExistPath); 288 } 289 290 @Test(expectedExceptions = NotDirectoryException.class) 291 public void testListNotDirectory() throws IOException{ 292 Files.list(testFile); 293 } 294 295 @Test(expectedExceptions = IOException.class) 296 public void testFindNoExist() throws IOException{ 297 Files.find(notExistPath, Integer.MAX_VALUE, (p, bfa) -> true); 298 } 299 300 @Test(expectedExceptions = IOException.class) 301 public void testLinesNoExist() throws IOException{ 302 Files.lines(notExistPath, UTF8); 303 } 304 305 @Test(expectedExceptions = IOException.class) 306 public void testWalkNoExist() throws IOException{ 307 Files.walk(notExistPath); 308 } 309 310 @Test(expectedExceptions = IOException.class) 311 public void testWalkNoExistWithDepth() throws IOException{ 312 Files.walk(notExistPath, Integer.MAX_VALUE); 313 } 314 315 public void checkFilesList(Path checkPath){ 316 try { 317 assert(Files.isDirectory(checkPath)); 318 Files.list(checkPath).filter(p -> Files.isDirectory(p)).forEach(p -> checkFilesList(p)); 319 assertEquals(Files.list(checkPath).filter(p -> Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)).count(), 320 Files.list(checkPath).filter(p -> Files.isSymbolicLink(p)).count()); 321 assertTrue(Files.list(checkPath).filter(p -> Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)).allMatch(file -> contentRevered(file))); 322 } catch (IOException ex) { 323 throw new RuntimeException(ex); 324 } 325 } 326 327 private boolean contentRevered(Path path) { 328 try (BufferedReader reader = Files.newBufferedReader(path, UTF8)){ 329 String fileName = path.getName(path.getNameCount() -1).toString(); 330 String reversed = new StringBuilder(reader.readLine()).reverse().toString(); 331 return (fileName.equals(reversed)); 332 } catch (IOException ex) { 333 throw new RuntimeException(ex); 334 } 335 } 336 }